Dreamteam: Selenium WebDriver and FitNesse

9

18. January 2013 by Michael Wowro

This year’s fantastic Hackathon at immobilenscout24.de in Berlin, offered me a productive environment (Club-Mate, pizza and really nice talks to really smart people) to dive deeper in the wiring of Selenium and FitNesse. And here we go:

Prerequisites
Read this article to find an overview of testing-frameworks and their use for acceptance testing.
Read Specification by Example, as FitNesse is a cool tool for that approach.
Read my guide to setup Selenium.
Read my guide to setup FitNesse.

Prologue
My primary goal, that I want to accomplish with any acceptance-test-framework: I want the non-programmers (managers, product owner, …) to understand which tests are implemented for their web-application yet – and which tests are still missing. I want to be sure, that the tests I (as a test-automater) have in my mind, really meet the requirements. The responsibles for the business-logic of a web-application should be able to check that at a glance. Additionally I like to give them a tool to easily change/enhance the test-data and simply push a test-button to get immediate feedback from their web-application (or its staging page). And yes, I’m really talking about automated functional tests with Selenium WebDriver.

Concrete
I’m presenting a really simple example to just show one possible wiring between Selenium and Fitnesse (without using Page Object-Pattern and just running Selenium locally).
In the specification we have everything lovely included: descriptive text, nice pictures/drafts of your feature and you have a button that executes the specifiation of that feature = the feature-test:

wiki-page

This pretty specification was created with that piece of code:

!*< [configurations]
!define TEST_SYSTEM {slim} 
!path C:\Users\IT Kosmopolit\Dropbox\IT Kosmopolit\Blogging\Fitnesse
!path C:\Users\IT Kosmopolit\Dropbox\IT Kosmopolit\Blogging\Fitnesse\selenium-server-2.28.0\selenium-2.28.0\selenium-server-standalone-2.28.0.jar

|import|
|de.itkosmopolit.fixtures|
*!

Test if the page title is displayed correct (case-sensitive), after search for "Cheese!"

!img http://www.public-domain-image.com/cache/food-and-drink-public-domain-images-pictures/cheese-public-domain-images-pictures/port-salut-cheese_w128.jpg

|Test Google page title|
|textInTitle|isTitleCorrect?|
|Google|yes|
|google|no|
|bing|no|

With !*< [configurations] I start an invisible block.
With !define TEST_SYSTEM I select the engine.
With !path I define a classpath.
|import| works like an import statement
Simple text doesn’t need any mark-up – just write it down.
!img brings us an image to the wiki-page.
And with |something| you start a table.

To dive deeper into the subject: In the TwoMinuteExample you find general information about the decision table, a main concept in FitNesse. In the MarkupLanguagReference you find more information about the markup I’ve used in the wiki-page:

If you like to have this nice specification on your computer, too:
1.) execute “localhost” in the address-bar (be sure to have set up FitNesse on your computer)
2.) push the Add-button
3.) select Test page
4.) write GoogleBasicTest for the Page name
5.) delete the default in the code box (!contents -R2 -g -p -f -h)
6.) copy&paste the above code in the code box
7.) click save

You can find your page under: http://localhost/GoogleBasicTest now.
Note: Be sure to name your future wiki-pages as WikiWords.

Now you have a cool specification, but it’s not doing anything valuable, if you push the Test-button. FitNesse uses so-called fixtures to wire a wiki-page with the Application Under Test. I appreciate the decision table as a plain, clear, noise-less way of defining all the scenarios of a feature (*waving at Gherkin*) – so find the appropriate description here. Note: Every row in the decision table represents one scenario.

Go to the folder in which your fitnesse-standalone.jar resides. Create there the folder-structure: de\itkosmopolit\fixtures, open an editor, copy&paste the following code in it and save it with the name TestGooglePageTitle.java (compare this name with the title of our decision table!)

package de.itkosmopolit.fixtures;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.util.List;

public class TestGooglePageTitle {
  private String text;
  private String pageTitle;
  
  public void table(List<List<String>> table) throws InterruptedException{
		// Create a new instance of the html unit driver
        // Notice that the remainder of the code relies on the interface, 
        // not the implementation.
        WebDriver driver = new FirefoxDriver();

        // And now use this to visit Google
        driver.get("http://www.google.com");

        // Find the text input element by its name
        WebElement element = driver.findElement(By.name("q"));

        // Enter something to search for
        element.sendKeys("Cheese!");

        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();

        // Check the title of the page
        pageTitle = driver.getTitle();
		
		driver.quit();
		
		Thread.sleep(500);
  }
  public void setTextInTitle(String text) {this.text = text;}
  public String isTitleCorrect() { 
		if (pageTitle.contains(text)) return "yes"; 
		else return "no";
  }
}

Note:
1.) Putting the Selenium code in the table-method feels a bit … hack-y, but … it works.
2.) Because of black magic, you need a Thread.sleep() – otherwise while executing you’d get the wrong(!) error-message: “Testing was interupted and results are incomplete.”

Then compile it, e.g. with your Command Prompt: (being in the folder where fitnesse-standalone.jar resides) javac -classpath "pathToSeleniumJAR\selenium-server-standalone-x.y.z.jar" de\itkosmopolit\fixtures\TestGooglePageTitle.java

And after pushing the test button you find this result:

success_of_fitnesse

The results are beautiful and I’m quite confident, that Selenium WebDriver & FitNesse are becoming a new dreamteam in the future. Anyhow consider, that I haven’t seen this aproach running on large projects yet – there may be some challenges …

Advertisements

9 thoughts on “Dreamteam: Selenium WebDriver and FitNesse

  1. Sitam says:

    Thanks Michael for the post. Got an error during “TestGooglePageTitle.java” compilation for the line : “public void table(List<List>)”.

    Error : “Syntax error on token “>>”, VariableDeclaratorId expected after this token”.

    Please help to resolve this issue.

    • Hi Sitam,

      thanks for visiting my blog. I’ve compiled it right now and on my computer it works. Are you sure, that you have copied the code of TestGooglePageTitle.java from my article correctly? If you move your mouse over the code section, a set of icons appear in the upper-right corner – select “copy to clipboard” then. If that doesn’t work please contact me directly: michael.wowro@it-kosmopolit.de

      Yours Michael

  2. mjvdende says:

    Test keeps running 🙂 nothing happens
    I know its little information but I did exactly what how you described it. Is there some logging somewhere?

  3. mjvdende says:

    Got this after 5 minutes running:
    Standard Error:
    Error: Could not find or load main class fitnesse.slim.SlimService

  4. chakrabarti says:

    Hi Michael,

    Thanks for your post. I keep getting a message saying “Could not invoke constructor” even though all of my classpath settings are correct. I ensured that the corresponding Java file has been compiled successfully prior to hitting the ‘Test’ button on the wiki page, and the path has been included in the wiki as well. Am I missing something with regards to the name? Does the Java class name need to exactly match the Wiki test name, or only the name of the decision table? Any help would be appreciated greatly. Thanks.

  5. Ray says:

    Thanks for the article. As you havent seen it running in a large project yet, I thought i’d share my experience if it helps anyone. I’ve worked with the selenium + fitnesse combination for about 5 years now. we have it running an extremely large test suite over several portal websites with high end functionality and very detailed charts/interactive charts etc.
    It is by no means a small project to get it to a very usable state. However, if you have the time, manpower and server resources to set up a testing grid, then I highly reccommend the fitnesse/selenium combination. We’ve hit just about every type of problem over the years, sometimes all most too much, but now we reap large benefits from it. Fully functional regression testing in any environment in under an hour. It’s a great approach.

  6. Ankit Nigam says:

    Thanks Michael for such a good blog.
    I was trying your example but unable to run it using selenium. After clicking the “Test” button on the page nothing happens. Browser goes into continuous loading mode.

    Below is my Fixture code:
    package com.ankit.fixture;

    import java.util.List;

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.firefox.FirefoxDriver;

    public class TestGooglePageTitle {
    private String text;
    private String pageTitle;

    public void setText(String text) {
    this.text = text;
    }

    public void table(List<List> table) throws InterruptedException{
    // Create a new instance of the html unit driver
    // Notice that the remainder of the code relies on the interface,
    // not the implementation.
    WebDriver driver = new FirefoxDriver();
    // And now use this to visit Google
    driver.get(“http://www.google.com”);
    // Find the text input element by its name
    WebElement element = driver.findElement(By.name(“q”));
    // Enter something to search for
    element.sendKeys(“Cheese!”);
    // Now submit the form. WebDriver will find the form for us from the element
    element.submit();
    // Check the title of the page
    pageTitle = driver.getTitle();
    driver.quit();
    Thread.sleep(500);
    }

    public String isTitleCorrect() {
    if (pageTitle.contains(text)) return “yes”;
    else return “no”;
    }
    }

    Fitnesse Table:

    !define TEST_SYSTEM {slim}

    !path F:\Fitnesse_Automation\Output_Jars\MyFitnesseSeleniumFixture.jar
    !path F:\Selenium_jars\selenium-server-standalone-2.4.0.jar

    |import |
    |com.ankit.fixture|

    |!-TestGooglePageTitle-!|
    |text |isTitleCorrect?|
    |Google|yes |
    |google|no |
    |bing |no |

    I have checked the class path and it seems fine.

    Any help will be greatly appreciated
    Regards,
    Ankit

  7. mjvdende says:

    Hi I got an email about a comment on this blog and wanted to point you to Xebium framework, see github. This is what I eventually ended up using because those guys took care of the integration of fitnesse en webdriver for you.

    cheers

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: