如何使用selenium和单个NUnit套件测试多个浏览器并保持DRY?

时间:2011-01-27 22:16:08

标签: selenium nunit cross-browser

我正在寻找一种方法来重用一个NUnit测试套件,而无需为每个浏览器复制整个套件。看起来我需要为每个浏览器安装一个新夹具。我可以从NUnit gui发送某种环境变量或配置设置来切换浏览器吗?见下文:

[TestFixture]
public class User
{
    private ISelenium selenium;
    private StringBuilder verificationErrors;

    [SetUp]
    public void SetupTest()
    {
        // TheBrowser = How do I populate this variable from the NUnit gui? 
        selenium = new DefaultSelenium("localhost", 4444, **TheBrowser**, "http://localhost:52251/");
        selenium.Start();
        verificationErrors = new StringBuilder();
    }

    [TearDown]
    public void TeardownTest()
    {
      ...
    }

    [Test]
    public void SearchUser()
    {
       ... 
    }

}

4 个答案:

答案 0 :(得分:6)

NUnit 2.5+支持通用测试夹具,这使得在多个浏览器中进行测试变得非常简单。 http://www.nunit.org/index.php?p=testFixture&r=2.5

构建以下内容将创建两个“GoogleTest”NUnit测试,一个用于Firefox,另一个用于IE。

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using System.Threading;

namespace SeleniumTests 
{
    [TestFixture(typeof(FirefoxDriver))]
    [TestFixture(typeof(InternetExplorerDriver))]
    public class TestWithMultipleBrowsers<TWebDriver> where TWebDriver : IWebDriver, new()
    {
        private IWebDriver driver;

        [SetUp]
        public void CreateDriver () {
            this.driver = new TWebDriver();
        }

        [Test]
        public void GoogleTest() {
            driver.Navigate().GoToUrl("http://www.google.com/");
            IWebElement query = driver.FindElement(By.Name("q"));
            query.SendKeys("Bread" + Keys.Enter);

            Thread.Sleep(2000);

            Assert.AreEqual("bread - Google Search", driver.Title);
            driver.Quit();
        }
    }
}

答案 1 :(得分:4)

好问题,很多人遇到这个问题。我喜欢使用IoC容器将浏览器注入我的测试用例。这让我可以将所有浏览器配置放入注入'mudule'

我使用Java绑定和Guice作为我的IoC容器,但是.Net中的主体是相同的。您希望类中的DefaultSelnium字段被注入。然后,您的测试使用此对象并在完成后将其处理掉。您可能会发现可以立即注入它,或者您可能需要在设置方法中创建对象。根据您的单元测试框架,您应该注意一些事项:

  • 您的测试类是否为每个测试创建了新的测试类? JUnit为每个要运行的测试创建测试类的新实例。 TestNG着名地废除了这个为每个包含的测试重用测试类对象。重用的问题是您注入的DefaultSelenium实例是为了骑行,如果您的测试并行运行或更改浏览器状态,可能会导致问题。
  • 延迟加载您的浏览器对象如果您的单元测试工具立即加载所有测试类,它将尝试预先创建浏览器对象,这是非常耗费资源的。

我相信你可以为我自己做得更好,但这些是我认为看起来很有希望的一些DI和NUnit链接。

NUnit integration tests and dependency injection

http://buildstarted.com/2010/08/24/dependency-injection-with-ninject-moq-and-unit-testing/

如果您不喜欢DI我听说有人使用工厂方法根据某些外部设置生成浏览器。

答案 2 :(得分:2)

以下是使用自定义XUnit DataAttribute为测试提供驱动程序的示例单元测试

using OpenQA.Selenium;
using SeleniumPageObjectsPatternExample.Attributes;
using SeleniumPageObjectsPatternExample.PageObjects;
using Xunit;
using Xunit.Extensions;

public class HomepageTests 
{
    [Theory]
    [Browser(Type.Firefox)]
    [Browser(Type.GoogleChrome)]
    public void HomepageLinksToBlogPage(IWebDriver webDriver)
    {
        // arrange 
        var expected = "some expected value";

        // act
        var homepage = new HomePage(webDriver, true);

        // assert
        Assert.True(homepage.BlogLink.Displayed);
        Assert.Equal(expected, homepage.Header.Text);
    }
}

这是自定义DataAttribute

using System.Reflection;
using OpenQA.Selenium;
using SeleniumPageObjectsPatternExample.WebDriver;
using Xunit.Extensions;

public class BrowserAttribute : DataAttribute
{
    private IWebDriver WebDriver { get; set; }

    public BrowserAttribute(Type browser)
    {
        this.WebDriver = WebDriverFactory.Create(browser);
    }

    public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, System.Type[] parameterTypes)
    {
        return new[] { new[] { this.WebDriver } };
    }
}

使用此WebDriverFactory

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;

using Type = SeleniumPageObjectsPatternExample.Attributes.Type;

public class WebDriverFactory
{
    public static IWebDriver Create(Type browser)
    {
        IWebDriver webDriver;

        switch (browser)
        {
            case Type.Firefox:
                webDriver = new FirefoxDriver();
                break;
            case Type.GoogleChrome:
                webDriver = new ChromeDriver();
                break;
            default:
                webDriver = new ChromeDriver();
                break;
        }

        webDriver.Manage().Window.Maximize();

        return webDriver;
    }
}

浏览器类型枚举

public enum Type
{
    Firefox,
    GoogleChrome
}

我建议你将枚举的名称从Type更改为其他...

答案 3 :(得分:0)

[SetUp]
    public void CreateDriver()
    {


        //driver = new TWebDriver();
        if (typeof(TWebDriver).Name == "ChromeDriver")
        {
            ChromeOptions options = new ChromeOptions();
            options.AddArguments("--incognito");
            driver = new ChromeDriver(options);
        }
        else if (typeof(TWebDriver).Name == "FirefoxDriver")
        {
            FirefoxOptions options = new FirefoxOptions();
            options.UseLegacyImplementation = false;
            options.SetPreference("browser.private.browsing.autostart", true);
            options.AddArgument("-private");
            driver = new FirefoxDriver(options);
        }
        else if (typeof(TWebDriver).Name == "InternetExplorerDriver")
        {
            InternetExplorerOptions options = new InternetExplorerOptions();
            options.BrowserCommandLineArguments = "-private";
            options.EnsureCleanSession = true;
            options.IgnoreZoomLevel = true;
            options.EnablePersistentHover = true;

            driver = new InternetExplorerDriver(options);

        } else
            driver = new TWebDriver();
    }