【问题标题】:Running cross browser tests using selenium and .NET Core使用 selenium 和 .NET Core 运行跨浏览器测试
【发布时间】:2020-01-14 20:03:28
【问题描述】:

我想使用 selenium 和 .NET Core 和 xUnit 在多个浏览器上运行 UI 测试。我发现很少有使用nUnitTestFixture 属性的示例。但是,我特别在寻找xUnit 解决方案。

我找到了this 解决方案,我可以在其中创建从DataAttribute 派生的我自己的属性

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

    public BrowserAttribute(string browser, string url)
    {
        switch (browser)
        {
            case "Chrome":
                Driver = new ChromeDriver();
                break;
             case "IE":
                Driver = new InternetExplorerDriver();
                break;
             case "Firefox":
                Driver = new FirefoxDriver();
                break;
        }
        Driver.Manage().Window.Maximize();
        Goto(url);
    }

    public void Goto(string url)
    {
        Driver.Url = url;
    }

    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        return new[] { new object[] { Driver } };
    }
}

然后测试看起来像

[Theory]
[Browser("IE", "http://www.google.co.uk")]
[Browser("Firefox", "http://www.google.co.uk")]
[Browser("Chrome", "http://www.google.co.uk")]
public void Test(IWebDriver driver)
{
    // Test something with IWebDriver    

    // i can do driver.Close() here to dispose IWebDriver        
}

这行得通 但是,它不会在测试完成后释放 IWebDriver,除非我在每个测试中显式调用 Close()

在 IWebDriver 上调用 Close() 的最佳选择是什么?

更新1

我创建了从BeforeAfterTestAttribute 派生的自定义属性,并在类级别应用了该属性。它奏效了。但是,当它调用GetCustomAttributes(..) 时,它会重新执行测试

public class AfterTest : Xunit.Sdk.BeforeAfterTestAttribute
{
    public override void After(MethodInfo methodUnderTest)
    {
        //at line below the test get executed again
        var attributes = methodUnderTest.GetCustomAttributes(typeof(BrowserAttribute),true);

        var att = attributes.First() as BrowserAttribute;
        att.Driver.Close();
        base.After(methodUnderTest);
    }
}

有什么方法可以在After 方法中获取 IWebDriver 的实例?

【问题讨论】:

  • 我会扫描一下 xunit slack,看看是否有其他人尝试过这种方法。 (疯狂猜测:也许使用 MemberData 你可以在每次使用后 Dispose ?)

标签: c# selenium selenium-webdriver .net-core xunit.net


【解决方案1】:

不幸的是,XUnit 不像 NUnit 那样支持 [TearDown] 方法。更多关于如何在 XUnit 中实现类似功能的信息可以在这里找到:http://mrshipley.com/2018/01/10/implementing-a-teardown-method-in-xunit/

如果您决定改用 NUnit,可以在此处参考此代码。我已经实现了我自己的 TestFixture 版本,它负责创建 WebDriver 实例以开始测试,并根据需要关闭实例。这是一个例子:

using System;
using NUnit.Framework;
using OpenQA.Selenium;

namespace MyTestAutomation.Framework
{
    public class BaseTestFixture
    {
       // this is your singleton webdriver instance -- this gets used throughout the testcase
        public static AndroidDriver<AppiumWebElement> Driver { get; private set; }

        [SetUp]
        public void BaseTestInitialize()
        {     
            // create webdriver instance here
            Driver = DriverFactory.Current.Create();

            // call test initialize, which can get overridden in each test case class    
            TestInitialize();
        }

        [TearDown]
        public void BaseTestCleanup()
        {
            // implement TestCleanup() override in your test case class
            TestCleanup(); // clean up after test case -- delete data, etc.

            // universal cleanup: close & quit driver
            Driver.Close();
            Driver.Quit();
        }

        protected virtual void TestInitialize()
        {
            // override this method in your test class & write initialize steps
        }

        protected virtual void TestCleanup()
        {
           // override this method in your test class & write additional cleanup steps
        }
    }
}

要在实际中使用它,您的测试类需要继承 BaseTestFixture,如下所示:

public class MyTestClass : BaseTestFixture
{
    protected override void TestInitialize()
    {
        // initialize your test case here
        // no need to create webdriver, base class method already does this
        // do something like log in to your application here, or navigate to URL
    }

    [Test]
    public void MyTest()
    {
    }

    protected override void TestCleanup()
    {
        // clean up your test case here -- log out, delete data, etc.
        // no need to implement Driver.Close(), base class method already does it 
    }
}

使用此代码示例,您可以编写一个测试夹具来处理创建 WebDriver 实例并在每次测试之前和之后关闭它。如果您希望在每个测试用例的开始和结束时实施更具体的步骤,您可以覆盖TestInitializeTestCleanup。 NUnit 的 [SetUp][TearDown] 方法确保这些初始化/清理方法只会在每个测试用例之前和之后运行。

【讨论】:

    【解决方案2】:

    您可以使用 Xunit.Abstractions;并使用 Dispose 方法。下面的代码还允许控制台输出,xunit 的一个严重痛点是没有。

    public class MyTestClass : IDisposable
    {
        private readonly ITestOutputHelper print;
    
    
        public MyTestClass(ITestOutputHelper output)
        {
            this.print = output;
            print.WriteLine("I'm the tear up");
    
        }
    
        public void Dispose()
        {
            print.WriteLine("I'm the tear down");
        }
    
        [Fact]
        public void MyTest1()
        {
    
            print.WriteLine("This is output from test 1");
        }
    
        [Fact]
        public void MyTest2()
        {
    
            print.WriteLine("This is output from test 2");
        }
    
        [Fact]
        public void MyTest3()
        {
    
            print.WriteLine("This is output from test 3");
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-26
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      相关资源
      最近更新 更多