Monday, February 20, 2012

Browser Specific TestFixtures Sharing Tests

I will get to WebDrivers running in parallel next week, for now something even more fun: How to share Tests across browser specific TestFixtures with WebDriver.

When writing a unit test to test a webpage, you will want to duplicate that test against multiple browsers. How do we do accomplish this feat? Inheritance!

Step 1: SetUpFixture

First we need to create a SetUpFixture that will manage our WebDrivers. This will be largest and most complex class of our demonstration.

[SetUpFixture]
public class SetUpFixture
{
    private static IWebDriver _internetExplorerDriver;
    private static IWebDriver _chromeDriver;
 
    public static IWebDriver InternetExplorerDriver
    {
        get
        {
            if (_internetExplorerDriver == null)
            {
                DisposeDrivers();
                _internetExplorerDriver = new InternetExplorerDriver();
            }
            return _internetExplorerDriver;
        }
    }
 
    public static IWebDriver ChromeDriver
    {
        get
        {
            if (_chromeDriver == null)
            {
                DisposeDrivers();
                var dir = ConfigurationManager.AppSettings["chrome"];
                _chromeDriver = new ChromeDriver(dir);
            }
            return _chromeDriver;
        }
    }
 
    private static void DisposeDrivers()
    {
        if (_internetExplorerDriver != null)
        {
            _internetExplorerDriver.Close();
            _internetExplorerDriver.Dispose();
            _internetExplorerDriver = null;
        }
        if (_chromeDriver != null)
        {
            _chromeDriver.Close();
            _chromeDriver.Dispose();
            _chromeDriver= null;
        }
    }
 
    [TearDown]
    public void TearDown()
    {
        DisposeDrivers();
    }
}

Step 2: Base Class

Second we create an abstract base class that will go select our WebDriver from the SetUpFixture via an abstract property.

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

Step 3: Tests

Write your tests in abstract classes that inherit from the base class.

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

Step 4: Driver Specific TestFixtures

Create a test fixture for each permutation of browser and test class.

public class ChromeTestFixtureA : TestFixtureA
{
    public override IWebDriver WebDriver
    {
        get { return SetUpFixture.ChromeDriver; }
    }
}
 
public class InternetExplorerTestFixtureA : TestFixtureA
{
    public override IWebDriver WebDriver
    {
        get { return SetUpFixture.InternetExplorerDriver; }
    }
}

Step 5: Run!

Okay, next week I'll actually talk about running WebDrivers in parallel. :)

kick it on DotNetKicks.com

Enjoy,
Tom

5 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Nice Blog, My friend, you just saved my bacon :-) with the Xunit info

    ReplyDelete
  3. Good stuff. But you never actually did post about WebDrivers in parallel, did you? :)

    ReplyDelete
  4. Joel, here you go: http://www.tomdupont.net/2012/08/webdrivers-in-parallel.html

    ReplyDelete
  5. Hi Tom,
    this is very helpful, thanks for this!

    Only thing I am trying to figure out is if there is a possibility to dispose() after each testcase. So after TestfixtureA.Test1, so that TestFixtureA.Test2 starts on a new browser.

    thanks
    Davy

    ReplyDelete

Real Time Web Analytics