Search code examples
testngcucumber-jvmcucumber-javapicocontainer

Getting null value for the Scenario Context- cucumber pico container


Getting null value when tried to get the value in steps given in second scenario. However I am able to get the value, when I tried in same steps.

Feature File
Feature: 01_Permission_Accept

  Scenario: 01_Is AUT installed and click on chapter 1
    Given Check AUT is installed  --> Here I am setting the value to context
    When Click on chapter - Chapter 1: App Fundamentals --> Here the value is retrieved

  Scenario: 02_Click on chapter 2
    When Click on demo chapter - Chapter 2: User Interface --> Here the value is null

Definition file:

public class MainScreenStepDefs {

TestContext testContext;

public MainScreenStepDefs(TestContext context) {
    this.testContext = context;
}

@Given("Check AUT is installed")
public void checkAUTIsInstalled() {
    boolean abc = testContext.getAppiumDriver().isAppInstalled(testContext.getConfiguration().androidAppPackage());
    SoftAssertions.assertSoftly(softAssertions -> softAssertions.assertThat(abc).as("Application \"" +testContext.getConfiguration().androidAppPackage()+"\" is not installed.").isTrue());
    testContext.getScenarioContext().setContext(ContextEnum.DEMO, "demo"); // Setting value to context
}

@When("Click on chapter - Chapter 1: App Fundamentals")
public void clickOnChapter1() {
    testContext.getPageObjectManager().getMainScreen().selectChapter1();
    String abc  = (String) testContext.getScenarioContext().getContext(ContextEnum.DEMO);
    System.out.println("Data :--------------- \t" + abc); //value getting successfully
}

@When("Click on demo chapter - Chapter 2: User Interface")
public void clickOnDemoChapter2() {
    testContext.getPageObjectManager().getMainScreen().selectChapter2();
    String abc  = (String) testContext.getScenarioContext().getContext(ContextEnum.DEMO);
    System.out.println("Data :--------------- \t" + abc); // ----null value
}}

Test Runner File. I am using TestNg as Runner. Inside @Beforesuite I am calling driver. here using @BeforeSuite, to avoid test to be closed after each scenario.

Using Lombok for getter and setter.

public class TestRunner extends AbstractTestNGCucumberTests {

    @Getter(AccessLevel.PROTECTED)
    private DriverManager mobileDriverManager;

    public static AppiumDriver<MobileElement> appiumDriver; // making static so this can be accessed directly
    Configuration configuration = ConfigurationManager.getConfiguration();

    @BeforeSuite(alwaysRun = true)
    public void setup() {
        mobileDriverManager = DriverFactory.getMobileDriverManager(DeviceTypeEnum.ANDROID);
        appiumDriver = mobileDriverManager.getMobileDriver(configuration.androidPlatformAndVersion(), configuration.androidDeviceUDID(), configuration.androidSystemPort(), AutomationName.ANDROID_UIAUTOMATOR2);
    }

    @AfterSuite(alwaysRun = true)
    public void tearDown() {
        getMobileDriverManager().quitAppiumDriver();
    }
}

TestContext.java Here before initilizing PageObjectManager, I am setting the AppiumDriver. Not doing so was giving error.

public class TestContext {

    @Getter @Setter
    private AppiumDriver<MobileElement> appiumDriver;

    @Getter
    private ScenarioContext scenarioContext;

    @Getter
    private PageObjectManager pageObjectManager;

    @Getter
    private Configuration configuration = ConfigurationManager.getConfiguration();

    public TestContext() {
        setAppiumDriver(TestRunner.appiumDriver); // This gives error, If I remove this.
        pageObjectManager = new PageObjectManager(getAppiumDriver());
        scenarioContext = new ScenarioContext();
    }
}

Please let me know am I doing the correct pico-container implementation.

Here is sample application github link: https://github.com/dipakkumar1225/DemoCucumberPicoContainerTestng.git


Solution

  • Objects are persisted along the single scenario. You set the value in one scenario and try to read it in another. This is why you get null.

    Dependency Injection allows you to share the state between steps - not between scenarios.

    If you have something to set up for each scenario you need to deal with Background.