Mam 2 funkcje plików (FeatureA i FeatureB). Pierwsze 2 kroki w plikach Feature są dokładnie takie same, więc chcę tylko napisać implementację tylko, a następnie może być ponownie używany przez inne pliki funkcji.

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

Mam klasa rodzicielska Base

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);
  }
}

Wdrażam poniżej 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
  }
}

Implementuj Feature B poniżej. (Ponownie używam kroku 1 i kroku 2 w Feature A, więc nie będzie musiał powielić go w 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? 
  }
}

Po uruchomieniu Feature A plik Gherkin, wszystkie dobre.

Po uruchomieniu pliku Feature B Gherkin, zmienna / referencyjna {x1}} zwraca mnie null.

Uruchamiam tryb debugowania i widzę initiate(browser, scenario); został przywołany, stąd public LandingPage landingPage; został utworzony przez inną klasę ({x2}}), przed krok w {{ X3}} jest wykonywany. Ale Class FeatureB widzi {x5}}

Jak więc korzystać z metody siedzącej w funkcji A i ponownego wykorzystania w funkcji B, C, D?

0
keylogger 19 kwiecień 2021, 10:03

1 odpowiedź

Najlepsza odpowiedź

Możesz osiągnąć to z wtryskiem zależności. Wtrysk zależności Umożliwia komponowanie definicji etapów mniejszych elementów, które można wstrzykiwać za pomocą konstruktora innych komponentów.

Najłatwiej się rozpoczniesz, jest z 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.

1
M.P. Korstanje 19 kwiecień 2021, 08:10