并行运行所有测试失败,会话ID无效

时间:2019-07-30 17:52:02

标签: c# selenium

我在一个测试课程中有4个测试,当我分别运行每个测试时,它们会通过。但是,当我全部并行运行它们时,它们将失败。我相信问题出在使用相同驱动程序实例的测试中。我已更改了要保护的驱动程序,但结果是相同的。并行测试失败。

WebDriver类:

using OpenQA.Selenium;

namespace TestAutomationFramework.Utilities
{
    public class WebDriver
    {
        protected IWebDriver Driver { get; set; }

    }
}

TestSetup类:

using System;
using NUnit.Framework;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;
using TestAutomationFramework.Utilities;

namespace TestAutomationFramework.Tests
{
    [TestFixture]
    public class TestSetup : WebDriver
    {
        public TestSetup()
        {
            var options = new ChromeOptions();
            Driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), options.ToCapabilities(), TimeSpan.FromSeconds(10));
            Driver.Manage().Window.Maximize();
        }

        // Test Setup, every test starts with this method
        [SetUp]
        public void StartTest()
        {
            Driver.Navigate().GoToUrl("https://google.com");
        }

        // Test Tear Down, every test ends with this method
        [TearDown]
        public void QuitTest()
        {
            Driver.Close();
            Driver.Quit();
        }
    }
}

BasePage类:

using System.Threading;
using OpenQA.Selenium;

namespace TestAutomationFramework.Pages
{
    public class BasePage
    {
        protected IWebDriver WebDriver;
        public BasePage(IWebDriver webDriver) => WebDriver = webDriver;

        #region Elements
        private IWebElement SearchField => WebDriver.FindElement(By.Name("q"));
        private IWebElement SearchButton => WebDriver.FindElement(By.Name("btnK"));

        #endregion

        public void SearchFor(string searchText)
        {
            //Thread.Sleep(2000);
            SearchField.SendKeys(searchText);
            SearchButton.Click();
            Thread.Sleep(5000);
        }

        public bool SearchResultShows(string whatShows)
        {
            Thread.Sleep(5000);
            var element = WebDriver.FindElement(By.XPath(
                "//*[@id='rhs_block']/div/div[1]/div/div[1]/div[2]/div[1]/div[2]/div[2]/div/div/div[2]/div/span"));
            return element.Text.Equals(whatShows);
        }
    }
}

DemoTest类

using NUnit.Framework;
using TestAutomationFramework.Pages;

namespace TestAutomationFramework.Tests
{
    [TestFixture]
    [Parallelizable(ParallelScope.All)]
    public class DemoTest : TestSetup
    {
        private BasePage _basePage;

        [Test]
        public void TestLogin()
        {
            const string query = "Test automation";
            _basePage = new BasePage(webDriver: Driver);
            _basePage.SearchFor(query);
            var shows = _basePage.SearchResultShows(whatShows: query);
            Assert.IsTrue(shows);
        }

        [Test]
        public void TestLogin2()
        {
            const string query = "Test automation";
            _basePage = new BasePage(webDriver: Driver);
            _basePage.SearchFor(query);
            var shows = _basePage.SearchResultShows(whatShows: query);
            Assert.IsTrue(shows);
        }

        [Test]
        public void TestLogin3()
        {
            const string query = "Test automation";
            _basePage = new BasePage(webDriver: Driver);
            _basePage.SearchFor(query);
            var shows = _basePage.SearchResultShows(whatShows: query);
            Assert.IsTrue(shows);
        }

        [Test]
        public void TestLogin4()
        {
            const string query = "Test automation";
            _basePage = new BasePage(webDriver: Driver);
            _basePage.SearchFor(query);
            var shows = _basePage.SearchResultShows(whatShows: query);
            Assert.IsTrue(shows);
        }
    }
}

问题:如何解决驱动程序实例,以便所有测试均不使用同一驱动程序?

2 个答案:

答案 0 :(得分:0)

根据Does NUnit create a new instance of the test fixture class for each contained test method nowadays?,所有测试的测试类实例均相同。 System.IO.File.Copy(inputFilePath, printerPath); 实例将在第一个测试运行后立即销毁(在方法Driver中),因此另一个测试将不再具有驱动程序。

尝试一下:

QuitTest

由于[TestFixture] public class TestSetup { private ThreadLocal<IWebDriver> _driver; protected IWebDriver Driver => _driver.Value; // Test Setup, every test starts with this method [SetUp] public void StartTest() { var options = new ChromeOptions(); _driver = new ThreadLocal<IWebDriver>(() => new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), options.ToCapabilities(), TimeSpan.FromSeconds(10))); Driver.Manage().Window.Maximize(); Driver.Navigate().GoToUrl("https://google.com"); } // Test Tear Down, every test ends with this method [TearDown] public void QuitTest() { Driver.Close(); Driver.Quit(); _driver.Dispose(); } } ,这可能会影响性能。我不确定。

答案 1 :(得分:0)

您总是可以使用驱动程序来编写字典,其中的键是线程ID,值是测试使用的驱动程序。

private static Dictionary<int, IWebDriver> drivers = new Dictionary<int, IWebDriver();

public static IWebDriver GetDriver()
{
    int id = Thread.CurrentThread.ManagedThreadId;
    if (!drivers.Keys.Contains(id))
    {
        SetupNewDriver();
    }
    return drivers[id];
}

在创建驱动程序时,将其添加到字典中(下一行来自SetupDriver方法):

drivers.Add(Thread.CurrentThread.ManagedThreadId, driver);

在我的项目中,我使用上述代码创建了DriverManager类,并且该类可以正常工作。缺点是您将无法为一个测试运行多个驱动程序。有可能使驱动程序的结构更复杂,但是我不需要这样做。