为什么要打开第二个(或第三个,或...)浏览器 window?
Why is a second (or third, or ...) browser window being opened?
我在 Java 中对 运行 Cucumber 和 Selenium 进行了准系统设置。
当我有一个功能文件 FirstScenario.feature
及其相应的步骤定义 FirstScenarioSteps.java
时,一切都符合预期。所以我添加了第二个组合,就在那时我注意到第二个浏览器 window 被打开,即使 运行 在第一个功能文件中只有一个场景。所以,我删除了组合,一切又好了。我发现只有第二步定义文件(没有功能文件)足以打开第二个浏览器 window。我很好奇所以我添加了第三步定义文件,并且打开了三个浏览器windows。
为什么每个场景打开(在这种情况下)三个浏览器 windows?最后两个 windows 打开保持空白(即不导航到网站)。
这是一个步骤定义文件。
public class ThirdFeatureSteps {
WebDriver driver;
// Tests or no tests, browser windows are still opened.
@Before
public void setup() {
System.setProperty(
"webdriver.chrome.driver",
System.getProperty("user.dir") + "\webdriver\chromedriver.exe"
);
driver = new ChromeDriver();
}
@After
public void teardown() {
driver.quit();
}
}
我明白@Before 和@After 是按场景执行的,这正是我想要的。
通过调用
driver = new ChromeDriver();
您正在创建一个新的驱动程序实例,这就是为什么您有三个浏览器,并且在您退出并打开新的之后。
如果你不想要3个实例,你需要让浏览器初始化class并将全局变量驱动设为静态,同时在初始化class中添加get方法,这将return 你的静态网络驱动程序。确保其他 classes 继承初始化 class.
比起只创建一个浏览器实例就可以操作。
结论更改@Before 和@After 方法。
正如 Gaj Julije 所提到的,hooks 是全局的,因此所有 before hooks 在每个特性之前执行。
您可以使用依赖注入来解决这个问题。当使用依赖注入时,Cucumber 将尝试创建步骤定义的构造函数依赖 类。这些依赖项是作为单例创建的,因此如果两个步骤定义 类 具有相同的依赖项,它们也会获得该依赖项的相同实例。
这可用于在不同的步骤定义文件之间共享信息(或网络驱动程序)或确保只有一个网络驱动程序。
这也比使用 static
网络驱动程序更好。如果不修改任何静态变量,则只能运行并行测试。
将 cucumber-picocontainer 依赖项添加到您的 pom.xml:
<dependencies>
[...]
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
然后为WebDriver
创建一个容器:
public class WebDriverContainer {
public WebDriver webdriver;
@Before
public void setup() {
System.setProperty(
"webdriver.chrome.driver",
System.getProperty("user.dir") + "\webdriver\chromedriver.exe"
);
webdriver = new ChromeDriver();
}
@After
public void teardown() {
webdriver.quit();
}
}
然后在步骤定义中使用容器。
public class FirstFeatureSteps {
WebDriverContainer container;
public FirstFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
public class SecondFeatureSteps {
WebDriverContainer container;
public SecondFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
public class ThirdFeatureSteps {
WebDriverContainer container;
public ThirdFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
但请记住,您可以在构造函数中使用 container.webdriver
,Web 驱动程序将 null
直到 before-hook 具有 运行.
我在 Java 中对 运行 Cucumber 和 Selenium 进行了准系统设置。
当我有一个功能文件 FirstScenario.feature
及其相应的步骤定义 FirstScenarioSteps.java
时,一切都符合预期。所以我添加了第二个组合,就在那时我注意到第二个浏览器 window 被打开,即使 运行 在第一个功能文件中只有一个场景。所以,我删除了组合,一切又好了。我发现只有第二步定义文件(没有功能文件)足以打开第二个浏览器 window。我很好奇所以我添加了第三步定义文件,并且打开了三个浏览器windows。
为什么每个场景打开(在这种情况下)三个浏览器 windows?最后两个 windows 打开保持空白(即不导航到网站)。
这是一个步骤定义文件。
public class ThirdFeatureSteps {
WebDriver driver;
// Tests or no tests, browser windows are still opened.
@Before
public void setup() {
System.setProperty(
"webdriver.chrome.driver",
System.getProperty("user.dir") + "\webdriver\chromedriver.exe"
);
driver = new ChromeDriver();
}
@After
public void teardown() {
driver.quit();
}
}
我明白@Before 和@After 是按场景执行的,这正是我想要的。
通过调用
driver = new ChromeDriver();
您正在创建一个新的驱动程序实例,这就是为什么您有三个浏览器,并且在您退出并打开新的之后。
如果你不想要3个实例,你需要让浏览器初始化class并将全局变量驱动设为静态,同时在初始化class中添加get方法,这将return 你的静态网络驱动程序。确保其他 classes 继承初始化 class.
比起只创建一个浏览器实例就可以操作。 结论更改@Before 和@After 方法。
正如 Gaj Julije 所提到的,hooks 是全局的,因此所有 before hooks 在每个特性之前执行。
您可以使用依赖注入来解决这个问题。当使用依赖注入时,Cucumber 将尝试创建步骤定义的构造函数依赖 类。这些依赖项是作为单例创建的,因此如果两个步骤定义 类 具有相同的依赖项,它们也会获得该依赖项的相同实例。
这可用于在不同的步骤定义文件之间共享信息(或网络驱动程序)或确保只有一个网络驱动程序。
这也比使用 static
网络驱动程序更好。如果不修改任何静态变量,则只能运行并行测试。
将 cucumber-picocontainer 依赖项添加到您的 pom.xml:
<dependencies>
[...]
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
然后为WebDriver
创建一个容器:
public class WebDriverContainer {
public WebDriver webdriver;
@Before
public void setup() {
System.setProperty(
"webdriver.chrome.driver",
System.getProperty("user.dir") + "\webdriver\chromedriver.exe"
);
webdriver = new ChromeDriver();
}
@After
public void teardown() {
webdriver.quit();
}
}
然后在步骤定义中使用容器。
public class FirstFeatureSteps {
WebDriverContainer container;
public FirstFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
public class SecondFeatureSteps {
WebDriverContainer container;
public SecondFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
public class ThirdFeatureSteps {
WebDriverContainer container;
public ThirdFeatureSteps(WebDriverContainer container){
this.container = container;
}
// use container.webdriver in your steps
}
但请记住,您可以在构造函数中使用 container.webdriver
,Web 驱动程序将 null
直到 before-hook 具有 运行.