据我们所知,当您使用 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/