繁体   English   中英

使用Selenium WebDriver和NUnit C#在Parallel中运行测试后,如何关闭多个浏览器窗口

[英]How to close down multiple browser windows after running tests in Parallel using Selenium WebDriver and NUnit C#

每次测试后,我目前正在使用以下代码关闭浏览器:

    [TearDown]
    public void StopBrowser()
    {
            if (Driver == null)
                return;
            Driver.Quit();
    }

当运行单个测试时,这很好用,但是当我使用NUnit的[Parallelizable]标签在并行中运行多个测试时,由于没有这样的会话错误,我的测试开始失败,无法连接到远程服务器错误,然后是对象引用错误最重要的是,这肯定与并行测试有关。

请在下面找到我在[SetUp]方法中使用的代码:

    public IWebDriver Driver { get; set; }

    public string TestUrl;

    [SetUp]
    public void Setup()
    {
        string Browser = "Chrome";

        if (Browser == "Chrome")
        {
            ChromeOptions options = new ChromeOptions();
            options.AddArgument("--start-maximized");
            Driver = new ChromeDriver(options);
        }
        else if (Browser == "Firefox")
        {
            FirefoxDriverService service = FirefoxDriverService.CreateDefaultService();
            service.FirefoxBinaryPath = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
            Driver = new FirefoxDriver(service);
        }
        else if (Browser == "Edge")
        {
            EdgeDriverService service = EdgeDriverService.CreateDefaultService();
            Driver = new EdgeDriver(service);
        }

基本页代码:

    public class BasePage<TObjectRepository> where TObjectRepository : BasePageObjectRepository
    {

        public BasePage(IWebDriver driver, TObjectRepository repository)
        {
            Driver = driver;
            ObjectRepository = repository;
        }



        public IWebDriver Driver { get; }
        internal TObjectRepository ObjectRepository { get; }
    }

BasePageObjectRepository代码:

public class BasePageObjectRepository
{
    protected readonly IWebDriver Driver;

    public BasePageObjectRepository(IWebDriver driver)
    {
        Driver = driver;
    }
}

我的测试只是在其相关页面内调用特定的函数,然后页面内的代码仅具有Selenium代码,该代码指向该Pages对象存储库中的元素,即

ObjectRepository.LoginButton.Click();

我不确定我的测试设置方式是否是部分导致问题的原因,但是对此我所能提供的任何帮助将不胜感激

编辑:在帮助中添加了更多我的代码:

BaseTest类:

    [TestFixture]
public class BaseTest
{
    public IWebDriver Driver { get; set; }

    public string TestUrl;


    [SetUp]
    public void Setup()
    {
        string Browser = "Chrome";

        if (Browser == "Chrome")
        {
            ChromeOptions options = new ChromeOptions();
            options.AddArgument("--start-maximized");
            Driver = new ChromeDriver(options);
        }
        else if (Browser == "Firefox")
        {
            FirefoxDriverService service = FirefoxDriverService.CreateDefaultService();
            service.FirefoxBinaryPath = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
            Driver = new FirefoxDriver(service);
        }
        else if (Browser == "Edge")
        {
            EdgeDriverService service = EdgeDriverService.CreateDefaultService();
            Driver = new EdgeDriver(service);
        }

        Driver.Manage().Window.Maximize();

        string Environment;
        Environment = "Test";



        if (Environment == "Test")
        {
            TestUrl = "https://walberton-test.azurewebsites.net/";
        }
        else if (Environment == "Live")
        {
            TestUrl = "";
        }

     }
}

[OneTimeTearDown]
public void TeardownAllBrowsers()
{
    Driver.Close();
    Driver.Quit();
}

测试之一的示例:

[TestFixture]
public class TimeLogsTestChrome: BaseTest
{
    [Test]
    [Parallelizable]
    [Category("Time Logs Test for Chrome")]
    public void AssertTimeLogsHeading()
    {
        Driver = new ChromeDriver();
        Driver.Manage().Window.Maximize();
        var loginPage = new LoginPage(Driver);
        var dashboard = new Dashboard(Driver);
        var timeSheets = new Timesheets(Driver);
        loginPage.GoTo("Test");
        loginPage.EnterEmailAddress("Valid");
        loginPage.EnterPassword("Valid");
        loginPage.ClickLoginButtonForLoginToDashboard();
        dashboard.ClickTimesheetsButton();
        timeSheets.AssertHeading();
        Driver.Close();
    }
}

测试基础代码示例:

internal class Timesheets : BasePage<TimesheetsPageObjectRepository>
{

    public Timesheets(IWebDriver driver) : base(driver, new TimesheetsPageObjectRepository(driver))
    {
    }

    internal void AssertHeading()
    {
        try
        {
            Assert.AreEqual("Timesheets", ObjectRepository.TimesheetHeading);
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    internal void ClickAddTimesheetButton()
    {
        ObjectRepository.AddTimesheetButton.Click();
    }

    internal void ClickSubmitTimeButton()
    {
        ObjectRepository.SubmitTimeButton.Click();
        Thread.Sleep(5000);
    }
}

具有大多数FindElement代码的页面对象存储库的部分示例:

internal class TimesheetsPageObjectRepository : BasePageObjectRepository
{

    public TimesheetsPageObjectRepository(IWebDriver driver) : base(driver) { }

    public string TimesheetHeading => Driver.FindElement(By.ClassName("pull-left")).Text;

}

灯具中的NUnit测试都共享相同的灯具实例。 这是程序员必须牢记的NUnit设计的基本原理之一,因为测试很容易通过使用共享状态来互相踩踏。 即使在非并行情况下,您也必须提防相互干扰的测试,但是并行会使情况变得更糟。

在您的情况下,最可能的罪魁祸首是灯具的Driver属性。 它是由每个测试的设置来设置的保存在其中的所有内容都由每个测试关闭。 那不是你想要的。

我还注意到,驱动程序被定义了两次,一次在灯具中,一次在基类中。 您尚未发布足够的代码来让我理解您为什么这样做,但这似乎有问题。

您必须确定夹具中的所有测试是否都打算使用相同的驱动程序。 我怀疑这不是您想要的,因为驱动程序本身可能具有可变状态。 但是,您可以使用任何一种方式进行设置。

要对所有测试使用相同的驱动程序 ,请使其成为灯具的属性。 用OneTimeSetUp方法初始化它,然后用OneTimeTearDown方法释放它。

要对每个测试使用不同的驱动程序 ,请不要使其成为属性。 而是在每个测试中初始化局部变量,然后在测试本身中释放它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM