Testing Drupal Websites Using WebDriver (Part 1)

I'm really enjoying Test-Driven-Development (TDD), combined with automated UI Tests for my Web apps. I love the confidence it gives me to code and be relatively certain I haven't broken anything which was previously tested...

Currently I'm writing tests for a custom Content Management System (CMS)  I co-wrote for my organization. The CMS is based on Drupal, but it's customized so much (via a very complex module) that it needs significant testing.

Drupal's implementation of SimpleTest does not work for me, as the testing is very complex, and I need more control than Drupal's SimpleTest module can offer.

For a tool to do the browser automation, I settled on Google's WebDriver project, which is also called Selenium2 and is a code-merge with the very popular Selenium framework. WebDriver is still in Beta, but regardless, I've found it to be stable, powerful, intuitive, and relatively easy to use. Alternative web-UI tesing frameworks exist, but I won't go in to them here. Suffice it to say, I like WebDriver because it is cross-browser, open-source, and backed by the venerable Selenium project, Simon Stewart, and Google. You can write WebDriver code in a bunch of popular programming languages including:

  • Java
  • C#
  • Python
  • PHP

But these implementations are ports of the Java API. Though my organization is not a Java shop, I chose to write the tests in Java, given that the Java implementation gets the most attention from the WebDriver developers.

The other tools I use to do my testing are the Eclipse IDE, the JUnit unit-testing framework, and subclipse. These three tools, along with WebDriver allow me to edit and compile test code, easily view test results using Eclipse's JUnit itegration, and use version control—all without ever leaving Eclipse. This is a great productivity boon.

WebDriver Code

Here's a basic (albeit a bit naive) example of a test class written in WebDriver. The test opens up a web page, finds a search input, types a search term, and submits the search. It then asserts that the first search term is what is expected:

package gov.nih.nlm.ncbi.cms.tests;

import static org.junit.Assert.*;
import org.junit.*;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WebDriver;
// For other browsers, there are other drivers...
import org.openqa.selenium.FirefoxDriver;

class MyFirstTestCase {

  private WebDriver driver = new FirefoxDriver();

  @Test
  public void testFirstResultIsCanine(){

    // Go to a URL
    driver.get( "http://www.example.com" );

    WebElement searchInput = driver.
      findElement( By.id("search-input") );

    searchInput.sendKeys( "dog" );

    /*
     * Submit the form, using the already 
     * captured input element. By default
     * WebDriver will wait until the submitted
     * page is fully loaded.
    */    
    searchInput.submit();

    WebElement firstLiEl = driver.
          findElement( By.
            xpath("id('results-list')/li[1]");
        
    assertEquals( "First result is "canine", 
      "canine", firstLiEl.getText() ); 
    
    driver.close();

  }
}

You can see more example-WebDriver code at WebDriver's Getting Started page, and you can familiarize yourself more with JUnit at JUnit's Getting Started Page.

In Part 2 of this series, I will move on to more real-world testing scenarios, when your test code must scale, and it becomes critical for your test-code to be readable and maintainable.

© 2010 Your Name.. Drupal theme by Kiwi Themes.