Sunday, September 20, 2009

What makes a good locator

What makes a good locator?

Its ‘robust’ – i.e. small changes to the HTML structure of a page are unlikely to break the locator. Locators that are very reliant on the structure of the html are not likely to be robust.
Its ‘reliable’ – i.e. the locator is a reliable way to identify the chosen element on the page.

Suggestions

If an id exists for the chosen element, and the id looks robust (i.e. the naming of the element looks like it’s not likely to change in the future), the id is a good choice.

e.g //CalendarLink

If the page name that a link is going to is unlikely to change, then using the filename as part of the locator works well. This is likely to continue to work even if the structure of the html on a page changes. However, care needs to be taken to ensure that the element being referenced is unique on a page. The following example uses the filename of the page link together with the id of a ancestor html element to ensure the locator is reliable and robust.

e.g. //ul[@id='MySpaceNav']/li/a[contains(@href, 'MyDesktop.aspx')]


If that doesn’t exist, look at the html surrounding the element to look for a good way to describe its location which is both robust and reliable. E.g. the following locator was used to uniquely identify the ‘My Space’ link in LPv2 and used the CSS class that is always applied to the element to achieve this.

e.g. //ul/li[contains(@class, 'rm-myspacelink')]/a


If none of the above are possible, and identifier based on the location of the html element needs to be used. This is most easily discovered by using Selenium IDE and clicking on an element.


A locator type can be an element id, an element name, an xpath expression, link text, and more.
A few examples:
selenium.click(“id=idOfThing”); //an id locator
selenium.click(“name=nameOfThing”); //a name locator
selenium.click(“xpath=//img[@alt='The image alt text']”); //an xpath locator
selenium.click(“dom=document.images[40]” ); //a DOM locator
selenium.click(“link=Test Page For Selenium”); //a link locator
selenium.click(“css=span#firstChild”); //a css locator

Thursday, September 10, 2009

What do testers hate about testing

"What do testers hate about testing?" was a question asked on a testing forum a while ago and the owner of the forum decided to pull the answers in to a presentation / list which, I think, makes interesting reading.

http://www.slideshare.net/rosiesherry/what-do-testers-hate-about-testing

I'd be interested to know if any of the points surprise you...

Test Automation

I've come across a couple of interesting blogs on automation recently, and I thought I'd share a couple of interesting ones.

http://blogs.msdn.com/imtesty/

http://thesocialtester.posterous.com/easy-tiger-dont-dismiss-record-and-playback-j

Saturday, September 5, 2009

Selenium Extensions

Selenium allows its functionality to be extended to provide additional features.

UI-Elements is an extension for the Selenium IDE and Remote Control that makes it possible to define a mapping between semantically meaningful names of elements on webpages, and the elements themselves.

e.g. instead of having a ‘click’ statement of
selenium.Click( “//ul/li[contains(@class, 'sharedspacespwd')]/a”);
It could be written:
selenium.Click( “ui=allPages::MySharedSpace()”)

This is VERY important as:
1. It makes the tests much more readable

2. It substantially reduces the maintenance overhead of the tests – e.g. if a link on the page changes, only the elements file would normally need to be updated, as opposed to having to update a large number of tests. It also makes it easier to define ‘locators’ for elements that are less likely to change.

The great thing about UI-elements is that it works with Selenium IDE, so when you record your tests, the UI-Element names are automatically recorded for use in your tests.



Friday, September 4, 2009

Run your first selenium test in Java

The following shows you step-by-step how to run your first Selenium RC application in Java.
1. It is assumed that you have JDK installed and set in your computer. If you are getting the version number(e.g javac 1.6.0_06) by running the following command in the Command Prompt, then your Java Compiler is installed and set correctly.
javac -version

2. Download Selenium RC.
3. Decompress Selenium RC. In my case, I decompress it to C:\.
4. 4. From the Command Prompt, go to the directory where selenium-server.jar is located.
cd C:\selenium-remote-control-1.0-beta-1\selenium-server-1.0-beta-1\

5. Then execute the following command to launch Selenium Server:
java -jar selenium-server.jar -interactive

6. The Google.java file containing the Java code below is our first Selenium RC application. What the code does is to launch Internet Explorer, open Google webpage and then search for Selenium RC.
/**
* Google.java
* Open Google webpage and search for "Selenium RC".
*/
import com.thoughtworks.selenium.DefaultSelenium;

public class Google
{
public static void main(String[] args)
{
final String sServerHost = "localhost";
final int iServerPort = 4444;
final String sBrowserType = "*iexplore"; // For Firefox, use *firefox
final String sBaseUrl = "http://www.google.com/";

DefaultSelenium oDefaultSelenium = new DefaultSelenium(sServerHost, iServerPort, sBrowserType, sBaseUrl);
oDefaultSelenium.start(); // Start Selenium.
oDefaultSelenium.setSpeed("5000"); // Wait 5 seconds for every instructions so that you can see what Selenium is doing.

// Open the main google webpage.
oDefaultSelenium.open("http://www.google.com/");

// Type "Selenium RC" into the search input field.
oDefaultSelenium.type("name=q", "Selenium RC"); // Use name locator to identify the search input field.

// Click on "Google Search" button
oDefaultSelenium.click("xpath=//input[@name='btnG']");

// Close the browser.
oDefaultSelenium.stop();
}
}


7.Execute the command below to compile the Java code.
javac -classpath C:\selenium-remote-control-1.0-beta-1\selenium-java-client-driver-1.0-beta-1\selenium-java-client-driver.jar Google.java

Note: You have to change C:\selenium-remote-control-1.0-beta-1\selenium-java-client-driver-1.0-beta-1\selenium-java-client-driver.jar to match the path where you put your selenium-java-client-driver.jar.
8. Execute the command below to run our application.
java -classpath C:\selenium-remote-control-1.0-beta-1\selenium-java-client-driver-1.0-beta-1\selenium-java-client-driver.jar;. Google


Using User-Extensions With Selenium RC

If you Google “Selenium RC user-extension” you will find different approaches to using this feature. Below, is the official Selenium suggested approach.
Example using C#
1. Place your user extension in the same directory as your Selenium Server.

2. If you are using client code generated by the Selenium-IDE you will need to make a couple small edits. First, you will need to create an HttpCommandProcessor object with class scope (outside the SetupTest method, just below private StringBuilder verificationErrors;) HttpCommandProcessor proc;

3.Next, instantiate that HttpCommandProcessor object as you would the DefaultSelenium object. This can be done in the test setup.proc = new HttpCommandProcessor("localhost", 4444, "*iexplore", "http://google.co.in/");

4. Instantiate the DefaultSelenium object using the HttpCommandProcessor object you created. selenium = new DefaultSelenium(proc);

5. Within your test code, execute your user-extension by calling it with the DoCommand() method of HttpCommandProcessor. This method takes two arguments: a string to identify the user-extension method you want to use and string array to pass arguments. Notice that the first letter of your function is lower case, regardless of the capitalization in your user-extension. Selenium automatically does this to keep common JavaScript naming conventions. Because JavaScript is case sensitive, your test will fail if you begin this command with a capital. inputParams is the array of arguments you want to pass to the JavaScript user-extension. In this case there is only one string in the array because there is only one parameter for our user extension, but a longer array will map each index to the corresponding user-extension parameter. Remember that user extensions designed for Selenium-IDE will only take two arguments.
string[] inputParams = {"Hello World"};
proc.DoCommand("alertWrapper", inputParams);

6. Start the test server using the -userExtensions argument and pass in your user-extensinos.js file. java -jar selenium-server.jar -userExtensions user-extensions.js