Dependency Injection - Cucumber Pico Container

16,251

Solution 1

You might be interested in my blog post where I use Pico Container to share state between two different Cucumber-JVM step classes, http://www.thinkcode.se/blog/2017/04/01/sharing-state-between-steps-in-cucumberjvm-using-picocontainer

Solution 2

You may not be able to implement inheritance but you can use constructors in step definitions class to pass on driver object reference from one class to another.

  1. Create a base/foundation class that initializes your driver object/ page objects classes. Use @Before annotation for defining setup and @After for defining teardown method.

public class Step_Def_Base {

    public static webDriverCreator test;
        @Before
        public void printScenario(Scenario scenario) {
            test = new webDriverCreator(this.getClass().getSimpleName());
            String className = this.getClass().getCanonicalName();
            System.out.println("********************************************************");
            System.out.println("Scenario: " + scenario.getName());
            System.out.println("********************************************************");
        }

        @After
        public void screenShotAndConsoleLog(Scenario result) {
              test.takescreenshot.takeScreenShotOnException(result);
            if (!(result.getStatus().contains("pass"))) {
                throw new RuntimeException(result.getName() + " got failed");
            }
            test.closeBrowserSession();
        }



}

  1. In your step definition class , create a constructor and instantiate the baseFoundation object with the context. This is where the pico-container plays its magical role of linking the driver object of step definition class with another class.

public class StepDefs_AltoroMutualLoginPage  {

    private Step_Def_Base contextStep;
    private webDriverCreator test;
    public StepDefs_AltoroMutualLoginPage(Step_Def_Base contextStep) {
        // TODO Auto-generated constructor stub
        this.contextStep = contextStep; // <-- This is where pico-containers starts working
        test = contextStep.test; // <-- Linking your driver object reference from the point where it is instantiated , i.e the base foundation class
    }

    @Given("^I am on test fire login page \"([^\"]*)\"$")
    public void alotoroMutualLoginPage(String url) {

        test.launchApplication(url);
        test.altoroMutual.launchLoginLink();
        test.altoroMutual.verifyUserIsOnLoginPage();

    }

Now you can get creative , and organize your page objects accordingly. I aggregated and instantiated all my page object classes inside the wrapper class that is returning the web driver object. You can see in the code, I am accessing altoroMutual pageObject class from test object.

Make sure you are using maven to manage all dev-dependencies . Following dependencies shall add pico container in your project.

        <dependency>
             <groupId>info.cukes</groupId>
             <artifactId>cucumber-picocontainer</artifactId>
              <version>1.2.5</version>
           <scope>test</scope>
        </dependency>
        <dependency>   
            <groupId>org.picocontainer</groupId>  
             <artifactId>picocontainer</artifactId>
             <version>2.14.3</version>
        </dependency>
Share:
16,251
snikt
Author by

snikt

Builder of BDD QA Automation Frameworks for testing Web Services.

Updated on June 04, 2022

Comments

  • snikt
    snikt almost 2 years

    I am having difficulty understanding and utilizing dependency injection in my situation. I want to use Pico-container (https://cucumber.io/blog/2015/07/08/polymorphic-step-definitions).

    This is my situation...I currently have one step definition class that contains all my selenium, and which is getting way too big:

    public class StepDefinitions{
        public static WebDriver driver; // a driver is returned here from a static Driver Factory Class
        LoginPage loginPage = new LoginPage(driver); //Page Object Model(s)
    
        @Before("setup")
        @After //screen snapshot
        @After("destroy")
        @Given //many methods with this tag
        @When  //many methods with this tag
        @Then  //many methods with this tag
    }
    

    Now I want to potentially have one class that contains my driver, POMs, and Hooks:

    public static WebDriver driver; //driver is returned from a static Driver Factory Class
    LoginPage loginPage = new LoginPage(driver); //Page Object Model(s)
    
     @Before("setup")
     @After
     @After("destroy")
    

    Another class that contains my @Given, one class that contains my @When, and one class that contains my @Then

    I then need to connect everything up right, so all classes can utilize the driver, hooks, and POMs. Cucumber does not support inheritance, so interfaces or Dependency Injection (Pico Container) is the way to go. I do not know how to do this, and I have studied online, I just cannot wrap my poor brain around it all.