Pico container for single DI

I am trying to use picocontainer for DI, but I still get my shared object multiple times instead of being automatically managed as a single one. Here's an example to illustrate. The ASteps and BSteps classes receive a SharedObject instance through their constructors. I expected this to be managed as a solid color pico container: instance only once, according to the Cucumber docs. Instead, I see that it is generated once for ASteps and once for BSteps:

Running my.domain.CucumberRunTest
 INFO [main] (CucumberHooks.java:15) - Executing before()
 INFO [main] (SharedObject.java:11) - SharedObject - instantiated
 INFO [main] (ASteps.java:21) - Executing a_step_one()
 INFO [main] (ASteps.java:26) - Executing a_step_two()
 INFO [main] (ASteps.java:31) - Executing a_step_three()
 INFO [main] (CucumberHooks.java:20) - Executing after()
 INFO [main] (CucumberHooks.java:15) - Executing before()
 INFO [main] (SharedObject.java:11) - SharedObject - instantiated
 INFO [main] (BSteps.java:23) - Executing b_step_one()
 INFO [main] (BSteps.java:28) - Executing b_step_two()
 INFO [main] (BSteps.java:33) - Executing b_step_three()
 INFO [main] (CucumberHooks.java:20) - Executing after()

      

What am I doing wrong? Here is the code:

package my.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class ASteps {

final Logger log = LoggerFactory.getLogger(getClass());
SharedObject sharedObject;

public ASteps(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}

@Given("^A step one$")
public void a_step_one() {
log.info("Executing a_step_one()");
}

@When("^A step two$")
public void a_step_two() {
log.info("Executing a_step_two()");
}

@Then("^A step three$")
public void a_step_three() {
log.info("Executing a_step_three()");
}
}

************************

package my.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class BSteps {

final Logger log = LoggerFactory.getLogger(getClass());
SharedObject sharedObject;

public BSteps(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}

@Given("^B step one$")
public void b_step_one() {
log.info("Executing b_step_one()");
}

@When("^B step two$")
public void b_step_two() {
log.info("Executing b_step_two()");
}

@Then("^B step three$")
public void b_step_three() {
log.info("Executing b_step_three()");
}
}

************************

package my.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class CucumberHooks {

final Logger log = LoggerFactory.getLogger(getClass());

@Before
public void before() {
log.info("Executing before()");
}

@After
public void after() {
log.info("Executing after()");

}
}

*********************

package my.domain;

import org.junit.runner.RunWith;

import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
public class CucumberRunTest {

}

**********************

package my.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SharedObject {

final Logger log = LoggerFactory.getLogger(getClass());

public SharedObject() {
log.info("SharedObject - instantiated");
}
}

      

+1


source to share


2 answers


The pico container cache is reset between scripts when the world is deleted at the end of the script.

It is very important for every project to avoid leaking state between scripts and make them isolated, so the order of the tests does not affect the results.



If you want to preserve state between script A and script B, you either need to handle it SharedObject

yourself, outside of the pico container, or you can make the dependency between the two scripts explicit - for example using Background .

+2


source


I hope it is not too late to answer your question.

Actually, you can have what you want. I saw that you also want to have one instance of your browser. You need to use static objects for this. I created a small class to avoid opening / closing the driver between each test. It is managed by a picocontainer. In your stepDefinition classes, you need to implement the "same" constructor.

Here's an example:

public class myStepDefinition{
    private Drivers context;
    public myStepDefinition(Drivers context){
        this.context = context;
        // whatever you want to do
    }
}

public class Drivers {
    private static boolean initialized = false;
    private static WebDriver driver;

    @Before
    public void initialize(){
        if (!initialized){
            initialized = true;
            driver = new FirefoxDriver();
            driver.manage().window().maximize();
            driver.get("http://www.myurl.url");
        }
    }

    public static WebDriver getDriver(){
        return driver;
    }
}

      



Keep in mind that after each test, you must return to the login page or your home page.

Hello,

Nicholas

+1


source







All Articles