c# - 在 SpecFlow 测试中使用 ChromeDriver

标签 c# .net selenium-webdriver selenium-chromedriver specflow

据我们所知,当您使用 SpecFlow 时,如果您重复使用另一个测试中的步骤,它会自动将其拉入并重复使用...但是,我遇到了一个问题,测试 A 登录我,测试 B 登录并确认主页是正确的,但是当我开始使用测试 B 时,测试 A 正在初始化 ChromeDriver,我的驱动程序想要打开另一个网页,导致测试失败,因为它打开了一个空网页。

我的问题是 - 如何使用该驱动程序而不打开另一个 Chrome 实例。这是我的“通用登录”的代码:

        private LandingPageCode landingPage;
        private HomePageCode HomePage;

        [Given(@"I have entered my username, password selected login")]
        public void GivenIHaveEnteredMyUsernamePasswordSelectedLogin()
        {
            driver = new ChromeDriver();
            driver.Url = ("my URL");
            landingPage = new LandingPageCode(driver);
            HomePage = new HomePageCode(driver); 

我在测试 B 上的代码在登录后验证主页:

    {
        private ChromeDriver driver;
        private HomePageCode HomePage;
        private LandingPageCode landingPage;


        [Given(@"Successfully log into Cal's website (.*)")]
        public void GivenSuccessfullyLogIntoOptix(Decimal p0)
        {
            driver = new ChromeDriver();
            HomePage = new HomePageCode(driver);
            landingPage = new LandingPageCode(driver);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
            Assert.AreEqual("HomePage", driver.Title);

最佳答案

我经常看到这个问题或相关问题( How to properly manage and access webdriver instances to avoid problems with parallel execution of tests? )。集成 Selenium 和 SpecFlow 可能很棘手。您需要利用SpecFlow附带的依赖注入(inject)框架,并使用before和after场景 Hook 来初始化Web驱动程序,然后将其注册到依赖注入(inject)容器。稍后在步骤定义类中,您需要为那些接受 IWebDriver 对象作为构造函数参数的类指定构造函数,并将其分配给每个步骤定义类上的字段。

[Binding]
public class WebDriverHooks
{
    private readonly IObjectContainer container;

    public WebDriverHooks(IObjectContainer container)
    {
        this.container = container;
    }

    [BeforeScenario]
    public void CreateWebDriver()
    {
        // or new FirefoxDriver or new WhateverDriver as long as it implements
        // the IWebDriver interface
        ChromeDriver driver = new ChromeDriver();

        // Make 'driver' available for DI
        container.RegisterInstanceAs<IWebDriver>(driver);
    }

    [AfterScenario]
    public void DestroyWebDriver()
    {
        var driver = container.Resolve<IWebDriver>();

        if (driver != null)
        {
            driver.Quit();
            driver.Dispose();
        }
    }
}

以及示例步骤定义文件:

[Binding]
public class LoginSteps
{
    private readonly IWebDriver driver;
    private readonly LoginPage loginPage;

    public LoginSteps(IWebDriver driver)
    {
        // Assign 'driver' to private field or use it to initialize a page object
        this.driver = driver;

        // Initialize Selenium page object
        this.loginPage = new LoginPage(driver);
    }

    [When(@"I go to the login page")]
    public void WhenIGoToTheLoginPage()
    {
        // Use 'driver' in step definition
        driver.FindElement(By.LinkText("Sign In")).Click();
    }

    [When(@"I log in")]
    public void WhenILogIn()
    {
        // Use Selenium page object in step definition
        loginPage.LogIn("testUser", "testPassword");
    }
}

这不仅允许您跨步骤定义文件共享 Web 驱动程序实例,而且还集中了创建和处置这些对象的逻辑,并使您更接近于允许并行测试执行。

另请参阅:Context Injection在 SpecFlow.org 上。

关于c# - 在 SpecFlow 测试中使用 ChromeDriver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58409700/

相关文章:

c# - 如何在 visual studio 中添加程序集 DocumentFormat.OpenXml.Wordprocessin

c# - Entity Framework 6 DbUpdateConcurrencyException 将新行添加到数据库时

c# - 未处理的异常 - 0x800a1391 - JavaScript 运行时错误 : 'SelectAllCheckBoxes' is undefined

c# - 如何在U-SQL查询中获取文件的完整路径

asp.net - 所有对 ASP.NET Web API 的请求都会返回 404 错误

Webdriver - java - 如何在执行操作后释放键

c# - 我应该在哪里连接到上下文以获得更好的性能?

c# - XmlTextReader - 它是否锁定文件?

c# - Selenium 无法处理 IE 中的确认证书弹出窗口

selenium-webdriver - 如何在 Chrome 浏览器中使用 Selenium Webdriver 创建新选项卡或窗口