Saturday, October 29, 2011

Maintainability 101


One of the biggest problem in the automation script development is the script maintenance. Even that there are a lot of widely accepted development methods for improving script maintenance, there are misconceptions that can easily direct testers in writing unmaintainable scripts.

The most popular methods in developing maintainable test code is the Page Objects pattern. Although using the Page Objects pattern will lead in a more maintainable code, the misuse of the pattern will only result in no more than adding an abstraction layer between the page under test and the test script each self. The misunderstandings in applying the pattern in order to create more maintainable test scripts come in the usage of the objects locators. The proper usage of the objects locators would result in the preferred maintainability and not the usage of the pattern. Taking into account that our object locators are locally declared (I totally agree with the analysis of Adam Goucher in his post http://element34.ca/blog/the-great-locator-location-debate) a poorly implementation of the pattern could result in using the page locator in more than one place inside the page object. For example having an input field for which we need to implement an object method to type in a value and an object method to read the inputed value we should use a locally declared locator as a static string instead of having a locator declaration in each method.
public void typeInputValue(Stringvalue){  
    selenium.type(“//input[@name='x']”);


public void readInputValue(){ 
   selenium.getValue(“//input[@name='x']”); 
}
public static final MY_LOCATOR=”//input[@name='x']”;

public void typeInputValue(String value){ 
   selenium.type(MY_LOCATOR); 


public void readInputValue(){ 
   selenium.getValue(MY_LOCATOR); 
}
In the first example a change in the objects locator would result in updating the object in to two places inside the page object rather than in one place as shown in the second example.
One of the goals in test script development is to make our test code more robust in locator breakages. As easily understood the single appearance of object locators in the page objects leads us toward this goal.
At this point I would like to thank Adam Goucher for his wonderful and extremely useful posts regarding test automation. For all it worth I would like to say that his posts lead the way in changing our test scripts to a more robust more maintainable test scripts.
Read More

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.

Read More