I have recently begun writing tests for the UI of our web application at work. We use a tool for automation of web application testing known as Sahi, mainly because it’s reliable, fast and easy to use. With a little guidance from an ever so patient co-worker who’s been working with Sahi for a while, I’m quickly getting the hang of it and using it effectively to produce and run my first tests. Yay!
Although Sahi allows you to record your interaction with the UI in order to facilitate scripting your tests, I’m learning that the process of crafting an effective test isn’t always that straightforward. Sometimes, it actually requires quite an amount of creativity. Consider this simple example. I was recently attempting to write a test for a part of the application that generates a form that contains, among other things, a couple of fieldsets. In each fieldset there’s a group of checkboxes which number is determined dynamically as the form is generated. Also in each fieldset, there’s a couple of links, one to select all checkboxes and one to clear all checkboxes in that fieldset. The main goal of my test was to verify that each fieldset had its own set of Select/Clear links that affected only the checkboxes inside that fieldset and not those inside the other fieldset. The tricky part was to select the right checkboxes to include in the assertions.
If you hover over them while holding the CTRL key, Sahi will show you the identifier(s) you can use to refer to different DOM elements. One common way to identify elements is by using indexes, ids and visible text. Since I couldn’t guarantee the visible text for the checkboxes in the form would remain the same as it was now, I decided it was better to use indexes to identify the checkboxes in the form, as in _checkbox(0), _checkbox(1) and so on. Consider the following:
<div> <!-- some other code --> <div> <fieldset> <input type="checkbox">checkbox 1</input> <input type="checkbox">checkbox 2</input> <input type="checkbox">checkbox 3</input> </fieldset> </div> <div> <fieldset> <input type="checkbox">checkbox 4</input> <input type="checkbox">checkbox 5</input> <input type="checkbox">checkbox 6</input> </fieldset> </div> </div>
Hovering over the first checkbox in the second fieldset will show the identifier _checkbox(3), which is good when you know for sure that this particular checkbox will always be in the second fieldset, but is not very useful in a dynamically generated form if you want to assert that only the checkboxes in the second fieldset are checked or cleared at a given time. What if something changes and next time you run the test you have more than three checkboxes in the first fieldset? Then _checkbox(3) will be in the first fieldset and if your test assumes that it is located in the second fieldset, it will fail for sure.
Fortunately for me, Sahi allows you to use _in when selecting elements. As in:
The code above selects the first checkbox inside the second DIV. I used this to my advantage to create a helper function that would allow me to assert that all checkboxes inside a given DIV element (Sahi couldn’t understand the fieldset tag) were checked or unchecked. I also noticed that, although hovering over the checkboxes gives you the global index of that particular checkbox in the page, if you select checkboxes relative to the element that contains them, their indexing will always start from zero. This way, I could use an expression such as this one inside a while loop to assert that all checkboxes inside a DIV were checked.
Where $i will always start from zero and $divnumber is the number of the DIV element that contains the checkboxes. The condition to continue the loop, of course, is that the checkbox exists inside the DIV in the first place.
Since there’s many ways to skin a cat, you may have found a different approach to the same problem. This one worked for me.