Cucumber JVM - 如何 re-use 方法写入其他功能 Class 正确?

Cucumber JVM - How to re-use method written in other Feature Class correctly?

我有 2 个功能文件(FeatureAFeatureB)。这些功能文件中的前两个步骤完全相同,所以我只想编写一次实现,然后可以 re-used 由其他功能文件

Feature A 

Given I use "<browser>"
When I navigate to the "www.google.com"
Then I will be able to do A

Feature B

Given I use "<browser>"
When I navigate to the "www.google.com"
Then I will be able to do B

我有parentclassBase

public class Base {

  public LandingPage landingPage;

  public synchronized void initiate(String browser) {

    // Do usual Chrome / Firefox WebDriver instantiation 

    this.landingPage = new LandingPage(); // Instantiate landingPage
  }

  public synchronized void navigateTo(String URL, Scenario scenario) throws InterruptedException {
    driver.get(URL);
  }
}

我实现下面的Feature A

public class FeatureA extends Base {

  @Given("I use {string}")
  public void i_use(String browser) {
    initiate(browser, scenario); // Call the method in parent class Base. This should instantiate this.landingPage = new LandingPage();
  }

  @When("I navigate to the {string}")
  public void i_navigate_to_the(String URL) throws InterruptedException {
    navigateTo(URL, scenario);
  }

  @Then("Then I will be able to do A")
  public void then_i_will_be_able_to_do_A() {
    //Do something specific to Feature A only
  }
}

我在下面实现 Feature B。 (我是 re-using Feature A 中的第 1 步和第 2 步,因此不需要在 Feature B 中复制它)

public class FeatureB extends Base {

  @Then("Then I will be able to do B")
  public void then_i_will_be_able_to_do_B() {
    //Do something specific to Feature B only

    log.debug("landingpage : " + super.landingPage); // Null.  Not sure why? 
  }
}

当我 运行 Feature A 小黄瓜文件时,一切都很好。

当我运行Feature B小黄瓜文件时,变量/引用super.landingPagereturns我null.

I 运行 调试模式,我可以看到 initiate(browser, scenario); 已被调用,因此 public LandingPage landingPage; 已被其他 Class (Class FeatureA) 实例化, 之前执行Feature B中的步骤。但是 Class FeatureB 看到 null

那么,如何使用特征 A 中的方法和 re-use 特征 B、C、D 中的方法?

您可以通过依赖注入来实现。依赖注入允许您编写可通过其他组件的构造函数注入的较小组件的步骤定义。

最容易上手的是cucumber-picocontainer

<dependencies>
  [...]
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-picocontainer</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
  [...]
</dependencies>
public class WebDriverContainer {

   private final Webdriver delegate;

   // Create webdriver instance here
   // as needed by invoking a method from your step definitions.
   // or something more advanced: https://github.com/cucumber/cucumber-jvm/tree/main/picocontainer#step-scope-and-lifecycle

   // note that before and after hooks can also be used here to do the clean up/setup.
}
public class FeatureA {

  private WebDriverContainer webdriver;

  public FeatureA(WebDriverContainer webdriver){
      this.webdriver = webdriver;
  }
  
  // Use webdriver container in your steps

}
public class FeatureB {

  private WebDriverContainer webdriver;

  public FeatureB(WebDriverContainer webdriver){
      this.webdriver = webdriver;
  }
  
  // Use webdriver container in your steps

}

https://github.com/cucumber/cucumber-jvm/tree/main/picocontainer