Thursday, April 8, 2010

Using Selenium

Client Setup

Initially, the developer would need to set up a project within the solution of the application they are working on called [ProjectName].UnitTests.

This project will need the following binary references: - nunit.framework.dll - ThoughtWorks.Selenium.Core.dll

Selenium Client Code

Once this is complete, the developer may create their own test cases from scratch or use the FireFox Plugin "Selenium IDE" to record interactions against a specific URL. (The IDE can be grabbed from the following location:

The selenium code uses the Nunit framework to create unit tests that can be run either with the nunit standalone application, or via a function call in the application. The code will look similar to the following:

using NUnit.Framework;
using Selenium;
namespace MCN0002.UnitTests
    public class PromoBuilder
        private ISelenium selenium;
        private string location;
        public void SetupTest()
            selenium = new DefaultSelenium("localhost", 5551,
           "*iexplore", Resources.Url);
        public void Teardown()
               "Has not redirected to the success page.");
        public void DateValidation()
           "ctl00_ContentPlaceHolder1_ctlPromoEditor_ddlPromoStart_Day", "label=31");
           "ctl00_ContentPlaceHolder1_ctlPromoEditor_ddlPromoStart_Month", "label=11");
            location = selenium.GetLocation();

Server Setup

In order to run the Selenium Client successfully, the developer will need the server application running on a remote machine or their own local machine. The server application (Selenium Remote Control) is built in java and can be found at the following URL:

Once this is downloaded, and assuming the java runtime is installed on the server, the following batch file can be run to start the server:

java -jar "C:\[Selenium Server Location]\selenium-server.jar" 
-interactive -port 5551

Where the port number is decided by the developer. (By default the port number is 4444, however the Firefox Selenium IDE plugin has already taken that)


Page Load timing

Any page load actions (i.e. Click of a button that postbacks, link etc.) must precede the following line of code:


Where the parameter is the number of miliseconds the process will timeout on while waiting for the page to load.

The reason for this is that the timing of any page load may be affected by many factors which include:
  • the amount of memory on the developer's machine which may take time to open the page using selenium
  • the website being tested is on a slow server
The above line of code will guarantee that if the next action is to check a checkbox, that checkbox will be found on the loaded page. This means that the developer could set the interval speed to as fast as they require.

Checking Error Messages

A common use of testing correct page behavior (especially for forms submission) requires testing whether appropriate error messages get displayed correctly or not. The problem is, however, that a validator on a form is displayed by javascript, which ultimately means that the error message is always on the web page even if it is visible or not. (i.e. the error message will not be an empty string if the validator is hidden).

Moreover, selenium doesnt read attributes for styling (i.e. display:none or visibility:visible).

The solution to this is to check the following:


If this returns 0 then the error is not displayed, otherwise it is displayed.

Get Attribute

In order to get an attribute of an exact control, the HTML must be interrogated. This interogation is similar to XPaths for XML. The below code gets the "src" attribute of an "img" element that has an attribute "id" of value "imgCheckTraction".

Test Data

Developers should always have a list of testable data that will always be the same no matter how many times you run the unit tests. Any time there is an alteration on the data for validation testing, the data should always be reverted to its original state. This will allow developer to create a new unit test assuming the test data is the original data that was initialized.

No comments :