为什么我的 IE 浏览器会使用 Selenium 和 Cucumber 启动两次?
Why is my IE browser getting launched twice with Selenium and Cucumber?
我正在使用 Selenium-Cucumber
编写非常基本的自动化测试,即启动 IE
浏览器并在最后关闭它。
问题是浏览器启动了两次。
除了几个 System.out
语句外,测试没有太多内容。我对基于 selenium
的自动化测试和 Cucumber
都是新手,无法理解为什么它会启动两次。
请指导。
BrowserConfig.java
public class BrowserConfig {
private static final String IE_DRIVER_EXE = "drivers/IEDriverServer.exe";
private static final String WEBDRIVER_IE_DRIVER = "webdriver.ie.driver";
private static final String BASE_URL = "https://www.google.com";
public static WebDriver getIEWebDriver() {
String filePath = ClassLoader.getSystemClassLoader().getResource(IE_DRIVER_EXE).getFile();
System.setProperty(WEBDRIVER_IE_DRIVER, filePath);
InternetExplorerOptions options = new InternetExplorerOptions().requireWindowFocus();
options.setCapability(INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
options.setCapability(ENABLE_ELEMENT_CACHE_CLEANUP, true);
options.setCapability(IE_ENSURE_CLEAN_SESSION, true);
options.setCapability(ACCEPT_SSL_CERTS, true);
options.setCapability("nativeEvents", false);
options.setCapability(INITIAL_BROWSER_URL, BASE_URL);
WebDriver driver = new InternetExplorerDriver(options);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
return driver;
}
public static void releaseResources(WebDriver driver) {
if (null != driver) {
driver.close();
driver.quit();
}
}
}
TestRunner.java
@RunWith(Cucumber.class)
@CucumberOptions(
plugin = {"pretty", "json:target/cucumber-reports/cucumber.json"},
features = {"src/test/resources/features"})
public class TestRunner extends ApplicationTests {
}
LoginStep.java
@Ignore
public class LoginStep {
WebDriver driver;
@Before
public void setup() {
if (this.driver == null) {
this.driver = BrowserConfig.getIEWebDriver();
}
}
@After
public void cleanUp() {
BrowserConfig.releaseResources(driver);
}
@Given("^The user is on the Login page$")
public void doLogin() {
System.out.println("The user is on the Login page");
}
@When("^The user enters the correct credentials on the Login page$")
public void setWelcomePage() {
System.out.println("The user enter the correct credentials on the Login page");
}
@Then("^The user is displayed Welcome page$")
public void validate() {
System.out.println("The user is displayed Welcome page");
}
}
HelpStep.java
@Ignore
public class HelpStep {
WebDriver driver;
@Before
public void setup() {
if (this.driver == null) {
this.driver = BrowserConfig.getIEWebDriver();
}
}
@After
public void cleanUp() {
BrowserConfig.releaseResources(driver);
}
@When("^The user clicks on the Help menu link from the Welcome page$")
public void setWelcomePage() {
System.out.println("The user clicks on the Help menu link from the Welcome page");
}
@Then("^The user is displayed Help page$")
public void validate() {
System.out.println("The user is displayed Help page");
}
}
help.feature
Feature: Check that the user is able to navigate to Help page
Background:
Given The user is on the Login page
When The user enters the correct credentials on the Login page
Then The user is displayed Welcome page
Scenario:
When The user clicks on the Help menu link from the Welcome page
Then The user is displayed Help page
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>cucumber-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cucumber-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<cucumber.version>4.2.3</cucumber.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<groupId>net.masterthought</groupId>
<artifactId>maven-cucumber-reporting</artifactId>
<version>3.14.0</version>
<executions>
<execution>
<id>execution</id>
<phase>verify</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<projectName>${project.artifactId}</projectName>
<outputDirectory>${project.build.directory}/cucumber-reports</outputDirectory>
<cucumberOutput>${project.build.directory}/cucumber-reports/cucumber.json</cucumberOutput>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
因为您正在初始化并在功能文件中两次调用您的驱动程序。
Background
部分功能文件首先在 LoginStep.java
中初始化浏览器,然后您的 Scenario
也在 HelpStep.java
中初始化浏览器。
我更喜欢使用全局 Hooks.java
class 作为 @Before
和 @After
挂钩,并在不同的 .java
class 之间注入驱动程序。
找到解决方案。下面的示例代码与原始 post 不同,但这解决了问题。添加了包含通用步骤的新 class "Hooks.java",并从功能文件中删除了 "Background"。这有助于解决问题。
Hooks.java
public class Hooks {
public static WebDriver driver;
@Before
public void setUp() {
System.out.println("Into the setup method of AccountStep...");
driver = BrowserConfig.getDriver();
}
@After
public void cleanUp() {
System.out.println("Into the cleanUp method of AccountStep...");
if (null != driver) {
driver.close();
driver.quit();
}
}
}
help.feature
Feature: Check that the user is able to navigate to Help page
Scenario:
Given The user is on the Help page
When The user clicks on the links within the Help page
Then The user is navigated to that Help section
HelpStep.java
@Ignore
public class HelpStep {
private WebDriver driver;
public HelpStep() {
this.driver = Hooks.driver;
}
@Given("^The user is on the Help page$")
public void onPage() {
System.out.println("The user is on the Help page");
}
@When("^The user clicks on the links within the Help page$")
public void clickLinks() {
System.out.println("The user clicks on the links within the Help page");
}
@Then("^The user is navigated to that Help section$")
public void validate() {
System.out.println("The user is navigated to that Help section");
}
}
确保为每个功能指定带有标记的前后挂钩,为什么?好的,例如,您有两个名为 UsersFeature
和 ProductsFeature
的功能,并且您为 UsersFeature 和 ProductsFeature 创建了一些钩子,如之前的 initBrowser 和之后的 closeBrowser 当你 运行 没有任何标签的测试时会发生什么?让我告诉你,对于该测试的每个功能,它会 运行 宁两次或(并行 N 次)N = "number of the features in that test"
因此该测试中的所有 before 钩子将 运行即使有数百万个功能和所有后挂钩,也要首先进行测试,因此请确保在那个时候使用像 @Before('@users_feature') @After('@users_feature')
这样的标签,只有当测试使用 [=14] 执行功能场景时,挂钩才会 运行ing =]
我正在使用 Selenium-Cucumber
编写非常基本的自动化测试,即启动 IE
浏览器并在最后关闭它。
问题是浏览器启动了两次。
除了几个 System.out
语句外,测试没有太多内容。我对基于 selenium
的自动化测试和 Cucumber
都是新手,无法理解为什么它会启动两次。
请指导。
BrowserConfig.java
public class BrowserConfig {
private static final String IE_DRIVER_EXE = "drivers/IEDriverServer.exe";
private static final String WEBDRIVER_IE_DRIVER = "webdriver.ie.driver";
private static final String BASE_URL = "https://www.google.com";
public static WebDriver getIEWebDriver() {
String filePath = ClassLoader.getSystemClassLoader().getResource(IE_DRIVER_EXE).getFile();
System.setProperty(WEBDRIVER_IE_DRIVER, filePath);
InternetExplorerOptions options = new InternetExplorerOptions().requireWindowFocus();
options.setCapability(INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
options.setCapability(ENABLE_ELEMENT_CACHE_CLEANUP, true);
options.setCapability(IE_ENSURE_CLEAN_SESSION, true);
options.setCapability(ACCEPT_SSL_CERTS, true);
options.setCapability("nativeEvents", false);
options.setCapability(INITIAL_BROWSER_URL, BASE_URL);
WebDriver driver = new InternetExplorerDriver(options);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
return driver;
}
public static void releaseResources(WebDriver driver) {
if (null != driver) {
driver.close();
driver.quit();
}
}
}
TestRunner.java
@RunWith(Cucumber.class)
@CucumberOptions(
plugin = {"pretty", "json:target/cucumber-reports/cucumber.json"},
features = {"src/test/resources/features"})
public class TestRunner extends ApplicationTests {
}
LoginStep.java
@Ignore
public class LoginStep {
WebDriver driver;
@Before
public void setup() {
if (this.driver == null) {
this.driver = BrowserConfig.getIEWebDriver();
}
}
@After
public void cleanUp() {
BrowserConfig.releaseResources(driver);
}
@Given("^The user is on the Login page$")
public void doLogin() {
System.out.println("The user is on the Login page");
}
@When("^The user enters the correct credentials on the Login page$")
public void setWelcomePage() {
System.out.println("The user enter the correct credentials on the Login page");
}
@Then("^The user is displayed Welcome page$")
public void validate() {
System.out.println("The user is displayed Welcome page");
}
}
HelpStep.java
@Ignore
public class HelpStep {
WebDriver driver;
@Before
public void setup() {
if (this.driver == null) {
this.driver = BrowserConfig.getIEWebDriver();
}
}
@After
public void cleanUp() {
BrowserConfig.releaseResources(driver);
}
@When("^The user clicks on the Help menu link from the Welcome page$")
public void setWelcomePage() {
System.out.println("The user clicks on the Help menu link from the Welcome page");
}
@Then("^The user is displayed Help page$")
public void validate() {
System.out.println("The user is displayed Help page");
}
}
help.feature
Feature: Check that the user is able to navigate to Help page
Background:
Given The user is on the Login page
When The user enters the correct credentials on the Login page
Then The user is displayed Welcome page
Scenario:
When The user clicks on the Help menu link from the Welcome page
Then The user is displayed Help page
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>cucumber-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cucumber-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<cucumber.version>4.2.3</cucumber.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<groupId>net.masterthought</groupId>
<artifactId>maven-cucumber-reporting</artifactId>
<version>3.14.0</version>
<executions>
<execution>
<id>execution</id>
<phase>verify</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<projectName>${project.artifactId}</projectName>
<outputDirectory>${project.build.directory}/cucumber-reports</outputDirectory>
<cucumberOutput>${project.build.directory}/cucumber-reports/cucumber.json</cucumberOutput>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
因为您正在初始化并在功能文件中两次调用您的驱动程序。
Background
部分功能文件首先在 LoginStep.java
中初始化浏览器,然后您的 Scenario
也在 HelpStep.java
中初始化浏览器。
我更喜欢使用全局 Hooks.java
class 作为 @Before
和 @After
挂钩,并在不同的 .java
class 之间注入驱动程序。
找到解决方案。下面的示例代码与原始 post 不同,但这解决了问题。添加了包含通用步骤的新 class "Hooks.java",并从功能文件中删除了 "Background"。这有助于解决问题。
Hooks.java
public class Hooks {
public static WebDriver driver;
@Before
public void setUp() {
System.out.println("Into the setup method of AccountStep...");
driver = BrowserConfig.getDriver();
}
@After
public void cleanUp() {
System.out.println("Into the cleanUp method of AccountStep...");
if (null != driver) {
driver.close();
driver.quit();
}
}
}
help.feature
Feature: Check that the user is able to navigate to Help page
Scenario:
Given The user is on the Help page
When The user clicks on the links within the Help page
Then The user is navigated to that Help section
HelpStep.java
@Ignore
public class HelpStep {
private WebDriver driver;
public HelpStep() {
this.driver = Hooks.driver;
}
@Given("^The user is on the Help page$")
public void onPage() {
System.out.println("The user is on the Help page");
}
@When("^The user clicks on the links within the Help page$")
public void clickLinks() {
System.out.println("The user clicks on the links within the Help page");
}
@Then("^The user is navigated to that Help section$")
public void validate() {
System.out.println("The user is navigated to that Help section");
}
}
确保为每个功能指定带有标记的前后挂钩,为什么?好的,例如,您有两个名为 UsersFeature
和 ProductsFeature
的功能,并且您为 UsersFeature 和 ProductsFeature 创建了一些钩子,如之前的 initBrowser 和之后的 closeBrowser 当你 运行 没有任何标签的测试时会发生什么?让我告诉你,对于该测试的每个功能,它会 运行 宁两次或(并行 N 次)N = "number of the features in that test"
因此该测试中的所有 before 钩子将 运行即使有数百万个功能和所有后挂钩,也要首先进行测试,因此请确保在那个时候使用像 @Before('@users_feature') @After('@users_feature')
这样的标签,只有当测试使用 [=14] 执行功能场景时,挂钩才会 运行ing =]