Saturday, February 11, 2012

Sharing a WebDriver across TestFixtures

I absolutely love WebDriver.

WebDriver (also known as Selenium 2.0) is a web testing tool that is both useful and easy, which is a very rare find. If you are doing web development with ASP.NET, you need to take 30 minutes of your time and go try out WebDriver. That is all the time it will take to get you hooked.

WebDriver and NUnit

To launch a browser you need only new up a Driver object for that browser. I used to create a new Driver in my TestFixtureSetup, and then close and dispose of that in the testFixtureTearDown. However now that Firefox does not persist my windows login credentials it can be very frustrating to have to log back in for every test fixture.

A solution to this problem is simply to share a single WebDriver across multiple TestFixtures. Fortunately NUnit's SetUpFixture makes this very easy to do.

Step 1: Create a SetUpFixture

This class's SetUp method will be called once before any TestFixtures run, and then it's TearDown will be called once after all the TestFixtures have completed.

[SetUpFixture]
public class SetUpFixture
{
    public const string ProfileKey = "firefoxprofile";
 
    public static IWebDriver WebDriver { get; private set; }
 
    [SetUp]
    public void SetUp()
    {
        var profileDir = ConfigurationManager.AppSettings[ProfileKey];
        if (String.IsNullOrWhiteSpace(profileDir))
        {
            WebDriver = new FirefoxDriver();
        }
        else
        {
            var profile = new FirefoxProfile(profileDir);
            WebDriver = new FirefoxDriver(profile);
        }
    }
 
    [TearDown]
    public void TearDown()
    {
        if (WebDriver == null)
            return;
 
        WebDriver.Close();
        WebDriver.Dispose();
    }
}

Step 2: Create an abstract base class

This abstract class will use the TestFixtureSetUp to copy the static WebDriver that was initialized by the SetUpFixture. I also like to have a SetUp that will clear the browser, just to make sure you are navigation to a new page from a blank one.

public abstract class TestFixtureBase
{
    public IWebDriver WebDriver { get; private set; }
 
    [TestFixtureSetUp]
    public void TestFixtureSetUp()
    {
        WebDriver = SetUpFixture.WebDriver;
    }
 
    [SetUp]
    public void SetUp()
    {
        WebDriver.Url = "about:blank";
    }
}

Step 3: Make your TestFixtures inherit the base class

These TestFixtures will now share the static WebDriver.

[TestFixture]
public class TestFixtureA : TestFixtureBase
{
    [Test]
    public void Test1()
    {
        WebDriver.Url = "http://www.phandroid.com/";
        Assert.IsTrue(WebDriver.Title.StartsWith("Android Phone"));
    }
}
 
[TestFixture]
public class TestFixtureB : TestFixtureBase
{
    [Test]
    public void Test1()
    {
        WebDriver.Url = "http://www.reddit.com/";
        Assert.IsTrue(WebDriver.Title.StartsWith("reddit"));
    }
}

Step 4: Run those tests!

If you love .NET 4.0 then stay tuned, because in my next post I'll explore running WebDrivers in PARALLEL! See you next week. :)

kick it on DotNetKicks.com

Enjoy,
Tom

3 comments:

  1. WebDriver uses native automation and does not have the sandbox constraints of Selenium-RC. It's a little faster and does not require a server. Cool, right?

    Web Design Company Northeast Ohio
    http://www.digitaldevelopmentconsulting.com/web-design-services/

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete

Real Time Web Analytics