Saturday, October 1, 2011

Selenium WaitFor ...

One of the most difficult problems to overcome when developing automated test scripts is time synchronization. Black box testing is based on expecting specific results upon a specific user actions irrespectively of time. Thus the big question that comes in mind is “when to expect the results?” are the results produced instantly or it takes some time depending on the system load?

One of the solutions presented, is using the time delay available to the programming language used for the test script development. Using Selenium with Java Thread.sleep(“3000”); will do the job. But is this effective? If you are developing automated test scripts for small scale projects and time is not an issue maybe this is your solution; but its advisable to use time delays large enough to account for system slow downs under load.

In large scale projects static time delays are inefficient. Think the amount of time wasted when  hundreds of scripts, having  static time delays, are executed. For these cases the solution to time waiting problem is to use a dynamic waiting period. Dynamic waiting period is the time duration until the system reacts. Testing a web application the reaction of the system would be a page loading. For these cases selenium.WaitForPageToLoad(“3000”); comes in handy. Using WaitForPageToLoad command insures that the system reacts before results verification. Again in this process it is critical to allow large amount of delays to account for system slow downs due to overloading. In our tests it was observed that sometimes a page would load in 10 seconds and under load the page loading could take up to 1 minute, so we adjusted time delays to the observed maximum. The debate in using the WaitForPageToLoad method is what is an acceptable waiting period for a page to load? Is it 1 ,2 ,3 minutes? In debates like that I always like to consider the criticality of the system and the defined requirements for the time responses. In non critical systems with no time requirements defined, it is acceptable to use large delay times (do what you can for the functional tests to complete and the performance tests will optimize the system to react faster under load). In critical systems usually time reaction requirement are well defined so time delays can be extracted through them.

But what happens in systems implemented with Ajax were elements are dynamically refreshed without a page loading? Then the selenium.WaitForPageToLoad(“3000”); it is to no use. In these cases prefer to use the selenium.waitForCondition(); command. When I came up to this situation most of the examples I found to help me were referring me in using JavaScript with the WaitForCondition command. Although this was feasible, using Javascript would have increased the difficulty scale of test script development (taking into account that testers are not required to be experienced programmers) I preferred staying to selenium commands and Xpath references to find dynamically refreshed elements. In some cases I replaced the selenium.WaitForPageToLoad(“3000”); with the WaitForCondition statement in order to have more control into what I am expecting to be loaded.

So a selenium.WaitForPageToLoad(“3000”); can be replaced by


selenium.waitForCondition("selenium.browserbot.getCurrentWindow().document.getElementById('page-heading').innerHTML='New Offer'","10000");

In the above example the waiting condition is specifying which page load to expect according to the page heading. Obviously using the  WaitForPageToLoad statement could result in navigating to the wrong page something that could be avoided using the WaitForCondition statement.
In the above  WaitForCondition example I used the DOM to access the page heading and in the following example I will show how to use the  WaitForCondition using the Xpath


selenium.waitForCondition("selenium.isElementPresent(\"//div[@id='cboxContent']\");", "10000");

In the above example we wait until an element is present (The element's Xpath is specified by the id).

In conclusion WaitForCondition offers better control over the aforementioned solutions controlling what to expect and when thus resulting in test robustness.