top of page
Writer's pictureSridevi Ponnusamy

How to use Pico Container in Cucumber?


Why we need Pico Container?


Inheritance is not possible in Cucumber step definition class. What if we don't want to create objects for dependent class in step classes?


Then how we are going to use the dependent class in step definition classes.


The solution is using Pico container for dependency injection.


1. By using Pico container we can share the states between the steps in a single feature or multiple feature file.

2.Pico Container identifies dependencies by looking at the constructors of registered step definition classes ( Constructor Injection )



Let's create simple maven project for understanding the pico container.


Below is the folder structure for our demo project.























1. Add dependency in pom.xml


Add the following dependency (latest version) in the pom.xml


<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer -->
<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-picocontainer</artifactId>
    <version>7.8.0</version>
    <scope>test</scope>
</dependency>


2.Create two feature files like below.


Home.feature

@HomePage
Scenario: Validating the homepage
  Given User opens the google website
  When  User is on home page
  Then User should be able to enter the search key "Roses" in the       
  search box

Search.feature

@SearchResults 
Scenario: Validating the search results
   Given User is on google home page  
   When User enters search keyword "Roses"
   Then User should be navigated to search results page "Roses"

3. Driver initialization


Base class is created with driver setup, teardown functions etc.,


BaseClass.java

package base;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class BaseClass {
	public WebDriver driver;
	
	public void setup()
	{
		String path = System.getProperty("user.dir");
		System.setProperty("webdriver.chrome.driver",
				path+"/Drivers/chromedriver.exe");
		if(driver==null)
		{
			driver = new ChromeDriver();
		}
	}
	
	public void openBaseURL()
	{
		driver.get("https://www.google.com");
	}
	
	public void tearDown()
	{
		driver.quit();
	}	
}


4. Context Class


Driver initialization and Page objects creation is done in context class.


Context.java

package utilities;
import org.openqa.selenium.WebDriver;
import base.BaseClass;
import pageObjects.HomePage;
import pageObjects.SearchPage;

public class Context extends BaseClass {

	private  HomePage homePage;
	private  SearchPage searchPage;
	public Context()
	{
		setup();
	}
	
	public WebDriver getDriver()
	{
		return driver;
	}
	public HomePage getHomePage()
	{
		if(homePage==null)
		{
			homePage = new HomePage(driver);
		}
		return homePage;
	} 
	public SearchPage getSearchPage()
	{
		if(searchPage==null)
		{
			searchPage = new SearchPage(driver);
		}
		return searchPage;
	} 	
}


5. Step definition and page class


Now we can use context class objects in step definition classes for creating page objects and initializing driver,

by injecting Context object in constructer of step definition class. This is called constructor dependency injection.


Example:

public HomeStep(Context context)
{
    this.context = context;
    homePage = context.getHomePage();
    
}

Note : constructor should be public


Please refer the below step definition class and page class for further understanding.


HomeStep.java

package stepDefinitions;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import pageObjects.HomePage;
import utilities.Context;
public class HomeStep {
    Context context;
    HomePage homePage;
    public HomeStep(Context context)
    {
        this.context = context;
        homePage = context.getHomePage();
    }

    @Given("User opens the google website")
    public void user_opens_the_google_website() {
        context.openBaseURL();
        System.out.println("User opens the google website\n");
    }

    @When("User is on home page") 
    public void User_is_on_home_page() {
        System.out.println("User is on homepage\n");
    }

    @Then("User should be able to enter the search key {string} in the     
     search box")
    public void     
   user_should_be_able_to_enter_the_search_key_in_the_search_box(String 
   searchKey) {
        homePage.search(searchKey);
        System.out.println("User can enter the seach key\n");
    }
 }
   

HomePage.java

package pageObjects;

import java.time.Duration;

import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class HomePage {
	WebDriver driver;
	WebDriverWait wait;
	public HomePage(WebDriver driver){
			this.driver = driver;
			PageFactory.initElements(driver, this);
			wait = new 	
			WebDriverWait(this.driver,Duration.ofSeconds(1));
		}
	
	@FindBy (name ="q") WebElement searchBox;
	
	public void search(String searchKey)
	{
		wait.until(ExpectedConditions.visibilityOf(searchBox));
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			
		}
		searchBox.clear();
		searchBox.sendKeys(searchKey);
		
	}
	public void enterSearch()
	{
		searchBox.sendKeys(Keys.ENTER);
		
	}
}

SearchStep.java

package stepDefinitions;

import org.testng.Assert;
import io.cucumber.java.After;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import pageObjects.HomePage;
import pageObjects.SearchPage;
import utilities.Context;

public class SearchStep {
	
	Context context;
	SearchPage searchPage;
	HomePage homePage;
	
	public SearchStep(Context context)
	{
		this.context = context;
		searchPage = context.getSearchPage();
		homePage = context.getHomePage();
	}
	
	@Given("User is on google home page")
	public void User_is_on_google_home_page() {
		context.openBaseURL();
	    System.out.println("User is on google home page\n");
	    
	}
	@When("User enters search keyword {string}")
	public void user_enters_search_keyword(String searchKey) {
		System.out.println("User enters search keyword : 	       
		"+searchKey+"\n");
		homePage.search(searchKey);
		homePage.enterSearch();
	}
	
	
	@Then("User should be navigated to search results page {string}")
	public void user_should_be_navigated_to_search_results_page(String    	
	searchKey){
		if(searchPage.getPageTitle().contains(searchKey))
		{
			System.out.println("User is in search results page\n");
			Assert.assertTrue(true);
			
		}
	}	
}

SearchPage.java

package pageObjects;

import java.time.Duration;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SearchPage {
	WebDriver driver;
	WebDriverWait wait;
	public SearchPage(WebDriver driver){
			
			this.driver = driver;
			PageFactory.initElements(driver, this);
			wait = new WebDriverWait(this.driver,Duration.ofSeconds(1));
		}
	
	@FindBy (xpath ="") WebElement Title;
	
	public String getPageTitle()
	{
		return driver.getTitle();
	}
}

Highlights:


Before every scenario , constructor is injected with context objects. And this can be shared within steps of the scenario, present in same or different classes.


Hope this is useful!


Happy Testing!!!

7,005 views

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page