黄瓜spring WebDriver中的设计问题在@After方法中退出 [英] Design issue in Cucumber spring WebDriver quit in @After method

查看:152
本文介绍了黄瓜spring WebDriver中的设计问题在@After方法中退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用黄瓜,硒和黄瓜弹簧构建框架时遇到设计问题.我的预期行为是在每种情况下都退出WebdDriver实例.但是

I have a design issue when I am trying to build a framework using cucumber, selenium and cucumber-spring. My expected behavior is to quit WebdDriver instance for every scenario. But

这是我在 src \ main \ java

@Component
public class BasePage {
WebDriver driver;
 public BasePage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(driver, this);

 }
 public WebDriver getDriver() {
    return this.driver;
  }

}

这里是另一个页面对象类,它扩展了Base类.

Here is another page object class which extends the Base class.

@Component
public class LoginPage extends BasePage
{
public LoginPage(WebDriver webDriver) {
    super(webDriver);
}

@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[1]")
WebElement loginTextBox;

@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[2]")
WebElement passwordTextBox;

@FindBy(xpath="/html/body/app-root/s-login-pg/div/form/button")
WebElement loginButton;

public void openApplication(String url){
    driver.get(url);
    waitForPageToLoad();
}

public void inputUsername(String username){
    loginTextBox.sendKeys(username);
}

public void inputPassword(String password){
    loginTextBox.sendKeys(password);
}

public void clickLoginButton(){
    loginButton.click();
 }
}

Webdriver是使用Factory Design模式创建的.基于属性文件中提到的浏览器,它将创建所需的webdriver实例.而且这些驱动程序类不是使用 @Component

The webdriver is created with Factory Design pattern. Based on the browser mentioned in the properties file it will create the desired webdriver instance. And these Driver classes are not created with @Component

src/test/java 下的spring配置类,如下所示.

And spring configuration class under src/test/java as shown below.

@Configuration
@ContextConfiguration(classes={PropertiesContext.class})
@ComponentScan(basePackages = "com.company.project")
public class CucumberContext {

@Autowired
private String browser;

  @Bean(name = "webdriver", destroyMethod = "quit")
  public WebDriver getWebDriver() {
    WebDriver webdriver = null;
    webdriver = DriverManagerFactory.getManager(browser).getDriver();
    return webdriver;
  }
}

这是 src \ test \ java

public class StepDefinitions extends ParentSteps {

@Autowired
private LoginPage loginPage;

@Autowired
private HomePage homePage;

@Before
public void init() {
    if (System.getProperty("environment") == null) {
        System.setProperty("environment", "DEV");
    }
}

@After
public void tearDown(Scenario scenario) {
    if(loginPage.getDriver() != null) {
        loginPage.getDriver().quit;
    }
}

}

这是我在步骤定义"中的实际问题.对于每个测试方案如果我调用 driver.quit(),其余的测试方案将失败,并带有以下异常,因为在 @After

Here is my actual problem in the Step Definitions. For every Test Scenario If I call driver.quit() the remaining test scenarios will be failed with the below exception because the bean WebDriver killed in @After

org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
Driver info: driver.version: RemoteWebDriver

at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:125)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)

我收到此错误的原因是因为webdriver已关闭,这是一个注入的bean.对于每种黄瓜方案,是否有解决方案在@Before中创建wedriver并在@After中杀死webdriver?设计有什么缺陷吗?

The reason why I am getting this error is because the webdriver is closed which is an Injected bean. Is there any solution to create wedriver in @Before and kill webdriver in @After for each cucumber scenario? Is there any flaw in the design?

推荐答案

除了OP用作解决方案的@DirtiesContext之外.使用@Scope(SCOPE_CUCUMBER_GLUE)/@ Scope("cucumber-glue")进行了尝试.在每种情况下,都会创建并销毁Webdriver的唯一实例.

Apart from the @DirtiesContext used by OP as solution . Tried using @Scope(SCOPE_CUCUMBER_GLUE)/@Scope("cucumber-glue") . Unique instance of Webdriver is created and destroyed in each scenario.

参考

将Spring bean的作用域更改为SCOPE_CUCUMBER_GLUE会将其生命周期绑定到标准胶水生命周期.

Changing a Spring bean's scope to SCOPE_CUCUMBER_GLUE will bound its lifecycle to the standard glue lifecycle.

import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Scope;
import static io.cucumber.spring.CucumberTestContext.SCOPE_CUCUMBER_GLUE;

@Component
@Scope(SCOPE_CUCUMBER_GLUE)
public class MyComponent {
}

基本页面:

@Component
@Scope("cucumber-glue")
public class BasePage {
WebDriver driver;
 public BasePage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(driver, this);

 }
 public WebDriver getDriver() {
    return this.driver;
  }

}

基本页面:

@Component
@Scope("cucumber-glue")
public class LoginPage extends BasePage
{
public LoginPage(WebDriver webDriver) {
    super(webDriver);
}

@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[1]")
WebElement loginTextBox;

@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[2]")
WebElement passwordTextBox;

@FindBy(xpath="/html/body/app-root/s-login-pg/div/form/button")
WebElement loginButton;

public void openApplication(String url){
    driver.get(url);
   // waitForPageToLoad();
}

public void inputUsername(String username){
    loginTextBox.sendKeys(username);
}

public void inputPassword(String password){
    loginTextBox.sendKeys(password);
}

public void clickLoginButton(){
    loginButton.click();
 }
}

配置:

@Configuration
// Not define in example so commented @ContextConfiguration(classes= 
//{PropertiesContext.class})
@ComponentScan(basePackages = "com.company.project")
public class CucumberContext {

@Autowired
private String browser;

  @Bean(name = "webdriver", destroyMethod = "quit")
  @Scope("cucumber-glue")
  public WebDriver getWebDriver() {
      WebDriver webdriver = null;
      // Removed the factory initialization code. Used simple ChromeDriver
      webdriver = new ChromeDriver();
      return webdriver;
  }
}

步骤:

public class StepDefinitions extends ParentSteps {

@Autowired
private LoginPage loginPage;

@Autowired
private HomePage homePage;

@Before
public void init() {
    if (System.getProperty("environment") == null) {
        System.setProperty("environment", "DEV");
    }
}

@After
public void tearDown(Scenario scenario) {
   // Removed quit
   // if(loginPage.getDriver() != null) {
   //     loginPage.getDriver().quit;
  //   }
}
}

注意:所有chromeriver后台进程都将被杀死.

Note: All chromeriver background processes are killed.

这篇关于黄瓜spring WebDriver中的设计问题在@After方法中退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆