Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does dependency injection work in Cucumber?

I have been trying to inject webdriver into the steps. I have used this instructions and it works well.

The idea is to inject WebDriver into steps classes as a service. At the initial step, you need to add the following dependency.

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-spring</artifactId>
    <version>1.2.5</version>
    <scope>test</scope>
</dependency>

There are three main classes which are involved in the dependency injection. Here we introduce them one by one.

enter image description here

BaseUtil

BaseUtil is the class which has an attribute for WebDriverof Selenium. The class is quite simple:

public class BaseUtil {

 private WebDriver driver;

 public WebDriver getDriver() {return driver;}

 public void setDriver(WebDriver driver) { this.driver = driver;}
}

Hook

The Hook class contains @Before, @After. The method testInitialier() is responsible to load the the webDriver file and create an instance, while the method testTearDown() is responsible for closing the browser.

    public class Hook extends BaseUtil{

    BaseUtil base;


    @Before
    public void testInitializer(){
        File file = new 
            File(IgniteTaskApplication.class.getClassLoader().getResource("driver/chromedriver.exe").getFile());
        String driverPath=file.getAbsolutePath();
        System.out.println("Webdriver is in path: "+driverPath);
        System.setProperty("webdriver.chrome.driver",driverPath);
        base.setDriver(new ChromeDriver());
    }

    public Hook(BaseUtil base) {
        this.base = base;
    }

    @After
    public void tearDownTest(){
        base.getDriver().close();
    }
}

Steps

And the steps class contains the steps which came from compiled features file. To compile the feature file in Eclipse you need to have Eclipse-Cucumber plugin installed in your Eclipse.

public class ClickButton_Steps extends BaseUtil{
    BaseUtil base;

    public ClickButton_Steps(BaseUtil base){
        super();
        this.base=base;
    }

    @When("^I clcik on the button$")
    public void i_clcik_on_the_button() throws Throwable {
        cb=new ClickButtonPage(base.getDriver());
        cb.navigator();
    }

        // The other steps ...
}

How do i run it?

Open the feature file -> Run as -> Run with Junit

Question

I am wondering what is the order of running methods in a way which it leads to dependency injection?

I guess the order is as following:

  1. Junit calls @Before method which is testInitializer()
  2. The testInitializer()is in Hook class so it needs to make an instance of Hook class.
  3. It leads to call the constuctor of the Hook class.

But, i cannot understand the rest of the steps. Maybe even it does not true at all. I mean, I have a functional code but i cannot explain how it works?

like image 341
Sal-laS Avatar asked Jul 18 '17 09:07

Sal-laS


People also ask

What is Dependency Injection in Cucumber?

Dependency Injection. If your programming language is a JVM language, you will be writing glue code (step definitions and hooks) in classes. Cucumber will create a new instance of each of your glue code classes before each scenario.

How does PicoContainer work in cucumbers?

Cucumber scans your classes with step definitions in them, passes them to PicoContainer, then asks it to create new instances for every scenario.

What is the purpose of Cucumber Guice dependency?

Using Dependency Injection, we can move the creation and binding of the dependent objects outside of the class that depends on them. JVM-Cucumber supports many different dependency injection frameworks, and one of them is Guice.


1 Answers

As I understand you correctly you use JUnit as a test framework with cucumber-spring. JUnit provides the following lifecycle.

When you annotate the method with annotation @Before that it will call this method before each test that you have. As for @After could be used for cleaning resources and call after each test.

Your test flow when you run the test:

  • testInitializer
  • i_clcik_on_the_button
  • tearDownTest

In addition, you could use logging (slf4j) instead of System.out.println and it will be easier to track test flow.

like image 98
Levik Avatar answered Oct 16 '22 19:10

Levik