USE DALEKJS FOR UI TEST­ING

Se­bas­tian Golasch ex­plains how to use DalekJS for au­tomat­ing web ap­pli­ca­tion and page UI test­ing

net magazine - - CONTENTS -

Se­bas­tian Golasch ex­plains how to use DalekJS for au­tomat­ing UI test­ing

Imag­ine for one sec­ond, you’re one of the fron­tend de­vel­op­ers re­spon­si­ble for a large on­line shop­ping web­site called thames.com. The most used fea­ture of thames.com, be­sides shop­ping carts and ac­count man­age­ment, is the search box on the top of the page. If you search for an item, you’ll be sent to an over­view page show­ing all items matched by your search query. A click on the head­line link of one of the items leads you to the de­tail in­for­ma­tion page.

So far so good, but now your boss ap­proaches you with a new fea­ture re­quest. You add the code, change bits and pieces of the ex­ist­ing codebase and ev­ery­thing works per­fectly, on your ma­chine and in your browser. Quite hap­pily you push your code, get a cof­fee and by the time you come back, your boss is al­ready there, reporting that no cus­tomer is able to search for items in Chrome.

Roll­back time, but one of your col­leagues pushed some code in the mean­time. You merge it, ev­ery­thing breaks ... OK, let’s end this hor­ror story here. I bet that you had sim­i­lar ex­pe­ri­ences at some point in your ca­reer.

You may have tried to solve this is­sue by cre­at­ing lists that ev­ery de­vel­oper has to fol­low, some­thing like this: l Open browser X l Type my prod­uct into the search box l Click the but­ton next to the search box l Check if the ti­tle of the first re­sult is my prod­uct (new!) l Click the link in the head­line of the first item l Ver­ify the head­line of the de­tail page my prod­uct (new!) - ex­tended de­scrip­tion l Ver­ify the price of the item is $2.47 l Re­peat these steps in In­ter­net Ex­plorer 9, 10, 11, Fire­fox, Sa­fari etc

This is time con­sum­ing and er­ror prone. A tool to au­to­mate this work­flow is re­quired in or­der to be help­ful, so let’s con­sider the re­quire­ments.

HOW TO SOLVE

A tool should al­low us to write this kind of au­to­ma­tion helpers in JavaScript be­cause that’s the lan­guage all web de­vel­op­ers have in com­mon. Sec­ond, it should be an easy ab­strac­tion to en­able fron­tend de­vel­op­ers to break it down, in fact, it should be as easy as jQuery.

Speak­ing of jQuery, the in­stal­la­tion should be as pain­less as copy and past­ing jQuery plug-ins. No­body likes to read tons of blog posts, ex­pe­ri­ence hours of con­fig­u­ra­tion and need the ex­pe­ri­ence of a thou­sand-year-old alien time lord to get a tool work­ing. An­other im­por­tant point: the tools should be able to test your page in real browsers. As awe­some as head­less browsers like Phan­tomJS are,

these browsers aren’t the browsers your vis­i­tors will use. They are great, but test­ing with them won’t give you the se­cure feel­ing that your page ac­tu­ally works in your vis­i­tors’ browsers.

Util­i­ties we al­ready use in our process, like Grun­tJS ( grun­tjs.com), should work with our tool of choice. Also, the frame­work should be based on a stan­dard, if it ap­pears to be not the tool we need, we could re­place it with a tool that is based on the same stan­dard with the low­est ef­fort pos­si­ble.

Back in the days there wasn’t a sin­gle frame­work that matched all of the cri­te­ria! At that dis­ap­point­ing point in time, we de­cided to cre­ate our own to, fi­nally, have a tool handy that obeys our com­mands.

EN­TER DALEKJS

DalekJS ( dalekjs.com) is the tool that came out of the process. It’s based on the Web­driver ( www.w3.org/

TR/2013/ WD-web­driver-20130117) spec­i­fi­ca­tion, in­ter­acts with real browsers, has a Grun­tJS plug-in and a re­ally nice jQuery-like API that al­lows you to write your tests in JavaScript.

No­body likes to need the ex­pe­ri­ence of a thou­sand-year-old alien time lord

IN­STAL­LA­TION

As stated a few lines above, the in­stal­la­tion of such a tool should be as straight­for­ward as pos­si­ble. To serve this pur­pose, DalekJS has only one de­pen­dency, and that’s Node.js ( nodejs.org). Bun­dled with Node comes npm, a pack­age man­ager sim­i­lar to gem or Com­poser. You can use it from your ter­mi­nal to in­stall the DalekJS CLI tools like this:

npm in­stall - g dalek- cli

Af­ter this step, you should have a new com­mand in your ter­mi­nal avail­able named dalek dalek . To ver­ify that ev­ery­thing is fine, just ex­e­cute dalek dalek -v -v . Then you need to nav­i­gate to the root folder of the project that you want to test and ex­e­cute:

npm in­stall -- save- dev dalekjs

That will in­stall the test­ing frame­work along­side your project. Now, the only miss­ing step is cre­at­ing a folder where your tests will end up. For the sake of brevity, we call the folder test and place it in the root di­rec­tory of our project.

Now that the ba­sic setup is all done, you are ready to write your first test. To keep the learn­ing curve ris­ing at a slow pace, let’s first check if we can nav­i­gate the browser to the thames.com thames.com web­site and check if the ti­tle is as we ex­pect it to be.

The mod­ule.ex­ports mod­ule.ex­ports vari­able needs to be as­signed to an ob­ject that it­self con­sists of at least one func­tion. Within this func­tion, you’re then able to de­fine your test logic:

mod­ule. ex­ports = { ' Ti­tle is as ex­pected': func­tion ( test) { test. open(' http:// www.thames. com/')

. as­sert.ti­tle(' Thames. com: On­line Shop­ping for Elec­tron­ics', ' Ti­tle matches the ex­pec­ta­tions')

. done();

}

}

Be­fore run­ning this ex­am­ple, take a mo­ment to ex­plore the in­ner se­man­tics of the Ti­tle is as ex­pected func­tion. As you may have fig­ured out, Ti­tle is as

ex­pected is the name of our test. The only ar­gu­ment that gets in­jected into it holds all the power of defin­ing tests. Within the Dalek world, we use the terms ac­tions and as­ser­tions to dif­fer­en­ti­ate be­tween two kinds of meth­ods that live in our test in­stance.

DEFIN­ING AC­TIONS

Ac­tions de­fine an in­ter­face to con­trol the browser, point­ing it to a spe­cific URL, typ­ing some­thing into a form field, click­ing links etc. As­ser­tions are the coun­ter­parts of ac­tions; they send data back from the browser and en­able you to check parts of the page. As­ser­tions are al­ways pre­fixed with the .as­sert no­ta­tion. In the ex­am­ple above, we use the open method to nav­i­gate to thames.com and then use the ti­tle as­ser­tion to check the con­tent of the pages <ti­tle> el­e­ment. Note that this isn’t done via scrap­ing the page’s HTML, so if you change the page ti­tle via JavaScript, Dalek will get it. The ti­tle as­ser­tion takes two ar­gu­ments: the first one is our value to check against, and there­fore must be sup­plied. The sec­ond will help you to find your as­ser­tions in the test re­sults later on.

So, the test hasn’t been ex­e­cuted yet. Luck­ily, DalekJS comes bun­dled with the head­less Phan­tomJS browser, so if you save the list­ing above in a file called sim­ple.js in the newly cre­ated folder test , open up your ter­mi­nal, nav­i­gate to the root folder of your project and type dalek test/sim­ple.js . Your test will run and if ev­ery­thing worked, you’ll get an out­put that looks like the con­sole out­put in the tu­to­rial files (down­load here: netm.ag/dalek-252).

Check­ing the ti­tle of a page isn’t that spec­tac­u­lar and you could ar­gue that test­ing text con­tents is a waste of time, so let’s dive deeper into the avail­able func­tions. As in­di­cated, our lit­tle on­line shop has the abil­ity to search through its items us­ing a Google­like search form. The form con­sists of two el­e­ments: a text in­put and a sub­mit but­ton.

< form ac­tion=" search" name=" site- search" ac­ceptcharset=" utf- 8">

<in­put type=" text" id=" twotab­search­textbox" value="">

<in­put type=" sub­mit" value=" Go" class=" nav­sub­mit- in­put"> </ form>

To search for a spe­cific item, such as ‘Blues Broth­ers video tape’, you can add a sec­ond test unit to the

sim­ple.js file and place it right af­ter the func­tion you cre­ated be­fore:

mod­ule. ex­ports = { // ... ' Search works': func­tion ( test) {

test .type('# twotab­search­textbox', ' Blues Broth­ers VHS') . click('. nav- sub­mit- in­put') . done(); } // ...

}

This snip­pet will is­sue two ac­tions to the browser. It will type the search term ‘Blues Brother VHS’ into the in­put field with the ID #twotab­search­textbox . The other ac­tion will then look for the el­e­ment with the CSS class .nav-sub­mit-in­put and is­sue a click event that sub­mits the form.

Note that typ­ing the string into the text field will add one char­ac­ter af­ter the other, just like a real user would do it. This is nec­es­sary to fire all the events that a user would also trig­ger if they did it by hand. For the click ac­tion, an in­vis­i­ble cur­sor will be placed above the el­e­ment and the com­plete event cas­cade will be fired.

As­sum­ing that sub­mit will re­di­rect you to some sort of search re­sults page with match­ing items, you can check if the head­line of the first item is as we ex­pect. To do this, we will add two more meth­ods to our test:

// ... . click('. nav- sub­mit- in­put') .wait­ForEle­ment('# re­sult_0') . as­sert.text('# re­sult_0 . newaps a span').to. con­tain(' The

Blues Broth­ers [ VHS]', 'Ar­ti­cle de­scrip­tion is fine') . screen­shot(' items. png') . done(); // ...

The wait­ForEle­ment method is needed be­cause you need some sort of in­di­ca­tion that the site has been loaded. Given that, in this sce­nario, a #re­sult_0 child el­e­ment must ex­ist in or­der to check our item, we wait for this one un­til we con­tinue with other ac­tions and as­ser­tions.

The head­line de­scrib­ing the item in the re­sult page is hid­den in a nested <span> el­e­ment. As Dalek sup­ports CSS se­lec­tors, ac­cess­ing the el­e­ment is easy. The as­ser­tion tech­niques used here, check­ing the con­tents with the to.con­tain helper af­ter­wards, dif­fers from the as­ser­tion that we used to match the page ti­tle. This is be­cause we’re check­ing that the text con­tents of the el­e­ment aren’t ex­actly the same as re­quested, but at least con­tain the string. We call this ‘as­ser­tion helper’.

To keep the boss happy, we also added a ‘screen­shot’ method to take a pic­ture of the cur­rent state of the items over­view page.

US­ING REAL BROWSERS

One of the goals when cre­at­ing this tool was to fo­cus on real browsers. So far, the tests only ran in

Maybe one day, Daleks will be ready to in­vade all web de­vel­op­ment teams out there

Phan­tomJS, which cre­ates an ex­pe­ri­ence that is quite close to Sa­fari.

At the time of writ­ing, Dalek sup­ports Chrome, Fire­fox, In­ter­net Ex­plorer and Sa­fari on iOS. Some of the im­ple­men­ta­tions have more com­plete fea­tures than oth­ers, but we hope to fill these gaps in our fu­ture ver­sions.

To run your tests in Chrome, you need to in­stall the dalek-browser-chrome add-on. To do so, just go back to the ter­mi­nal and type npm in­stall dalek­browser-chrome --save-dev . Now run your tests again with dalek test/sim­ple.js -b chrome . The additional pa­ram­e­ter -b , the short­cut for --browser , tells DalekJS to run your tests in Chrome. The browser starts au­to­mat­i­cally and you can lean back to watch the magic hap­pen.

If you want to in­stall the In­ter­net Ex­plorer helper, ex­e­cute npm in­stall dalek-browser-ie --save-dev . If you have mul­ti­ple browser helpers in­stalled, you can chain them when start­ing the tests like this dalek test/sim­ple.js -b chrome,ie , or you can add a Dalek­file. json to your ap­pli­ca­tions root folder and then add the fol­low­ing con­tents:

{

" browser": ["chrome", " ie"]

}

If you want to au­to­mate a browser in a vir­tual ma­chine or on a dif­fer­ent com­puter, check this screen­cast: vimeo.com/78144005.

RE­PORTS

Run­ning tests this way is ab­so­lutely help­ful, but af­ter cre­at­ing dozens of them, you’ll get bored of scan­ning the ter­mi­nal out­put man­u­ally for er­rors. Also, au­to­mated tests are meant to run with­out a hu­man be­ing need­ing to check the re­sults. This is cru­cial in CI/CD en­vi­ron­ments where dozens of de­vel­op­ers work on the same ap­pli­ca­tion. To tackle this spe­cific prob­lem, Dalek has a plug-in con­cept for other out­put sce­nar­ios be­sides the de­fault con­sole out­put. Namely, JSON, JU­nit com­pat­i­ble XML and HTML.

Be­cause you’re not a ma­chine and more in­ter­ested in ‘hu­man com­pat­i­ble’ out­put, it’s more handy to in­te­grate the HTML re­porter for demo pur­poses.

Adding the re­porter is easy. Type npm in­stall dalekre­porter-html --save-dev and ex­e­cute the tests with the -r (short for ---re­porter ) flag like so dalek test/sim­ple.js -r con­sole,html . Af­ter the test, run a new di­rec­tory. re­port/dalek should ap­pear con­tain­ing an in­dex.html with a list if all passed and failed tests.

CON­CLU­SION

Now you know the ba­sics of how to au­to­mate your web apps tests in a sane way. There are so many more func­tion­al­i­ties, so I en­cour­age you to take a look at the doc­u­men­ta­tion ( dalekjs.com/pages/ doc­u­men­ta­tion.html), which gives hints and ex­am­ples on how to use it prop­erly.

A fair warn­ing: DalekJS is im­ma­ture. I can­not rec­om­mend bas­ing your en­tire app test­ing on it now be­cause it’s fairly young, in de­vel­oper pre­view mode and still needs to find its own iden­tity. API changes and other one-time er­rors will hap­pen.

How­ever, I don’t want to scare you off us­ing it. Give it a try. If you find a bug, re­port it, or bet­ter, send us a pull re­quest.

Daleks haven’t got­ten much love over the past few decades, but maybe one day, Daleks will be ready to in­vade all web de­vel­op­ment teams out there to make the web a bet­ter and less buggy place for all of us to surf in.

Newspapers in English

Newspapers from Australia

© PressReader. All rights reserved.