Ency
Ency

Reputation: 633

How to pass TestNG parameter into Cucumber?

I am trying to run my cucumber tests under different browser, so I have test.xml (yes, currently just one browser)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="SelfCare" verbose="1" thread-count="1" parallel="tests" configfailurepolicy="continue">
    <parameter name="environment" value="TEST" />
    <test name="Chrome">
        <parameter name="browser" value="chrome" />
        <parameter name="width" value="1024" />
        <parameter name="height" value="768" />
        <classes>
            <class name="TestNGRunner">
                <methods>
                    <include name="scenario"/>
                </methods>
            </class>
        </classes>
    </test>
</suite>

And this TestNG runner class, I am able to access parameter browser from this runner class, but I would need to pass this variable(s) to Cucumber where are create instance of browser based on passed variables. So far I use it without TestNG and I'm passing those variables through environment variables, however I assume this won't work if I run tests in parallel on different browsers.

import cucumber.api.CucumberOptions;
import cucumber.api.testng.CucumberFeatureWrapper;
import cucumber.api.testng.PickleEventWrapper;
import cucumber.api.testng.TestNGCucumberRunner;
import org.testng.annotations.*;

@CucumberOptions(
        plugin = {"html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "junit:target/cucumber-results.xml"},
        strict = true,
        extraGlue = {"src/test/resources/Hooks.java"},
        features = {"src/test/resources/Header.feature"}
)
public class TestNGRunner {
    private TestNGCucumberRunner testNGCucumberRunner;
    private String browser;

    @BeforeClass(alwaysRun = true)
    public void setUpClass() throws Exception {
        testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
    }

    @Parameters("browser")
    @BeforeTest
    public void beforeSuite(String browser) {
        System.out.println("Browser for this test set is " + browser);
        this.browser = browser;
    }

    @Test(groups = "Cucumber", description = "Runs Cucumber Feature", dataProvider = "scenarios")
    public void scenario(PickleEventWrapper pickleEvent, CucumberFeatureWrapper cucumberFeature) throws Throwable {

        testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
    }

    @DataProvider
    public Object[][] scenarios() {
        return testNGCucumberRunner.provideScenarios();
    }

    @AfterClass(alwaysRun = true)
    public void tearDownClass() throws Exception {
        testNGCucumberRunner.finish();
    }

}

Any ideas how to achieve that?

Upvotes: 1

Views: 6679

Answers (3)

Anil Jain
Anil Jain

Reputation: 69

    TestNG:
    ---------
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Sauce Demo Cucumber Test Automation">
        <parameter name="browser" value="Chrome" />
        <test thread-count="2" name="test" parallel="classes">
            <classes>
                <class name="com.automation.cucumber.runner.ui.SauceDemoRunner" />
            </classes>
        </test> <!-- Test -->
    </suite> <!-- Suite -->
    
    Step definitions base class:
----------------------------
    import org.openqa.selenium.WebDriver;
    import org.testng.Reporter;
    import org.testng.xml.XmlTest;
    
    public class BaseStepDefinition {
        WebDriver driver;
        XmlTest xmlTest;
    
        public BaseStepDefinition() {
            try {
                xmlTest = Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest();
                System.out.println(xmlTest.getParameter("browser"));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
    Step definitions class:
--------------------------------
    import io.cucumber.java.After;
    import io.cucumber.java.en.Given;
    
    public class SauceDemoStepDefinition extends BaseStepDefinition {
    
        @After
        public void tearDown() throws Exception {
    
        }
    
        @Given("^User is on login page$")
        public void user_is_on_login_page() throws Exception {
    
        }
    
    }

Upvotes: 0

Step 1. Runner Class shall extends AbstractTestNGCucumberTests and implement @Parameters and @BeforeTest annotations.

package com.jacksparrow.automation.suite.runner;

import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import com.jacksparrow.automation.steps_definitions.functional.BaseSteps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;

@CucumberOptions(features = "classpath:features/functional/",
                     glue = {"com.jacksparrow.automation.steps_definitions.functional" },
                   plugin = { "pretty","json:target/cucumber-json/cucumber.json",
                            "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
                   tags = { "@BAMS_Submitted_State_Guest_User" },
                   junit ={ "--step-notifications"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCukeTest extends AbstractTestNGCucumberTests {

    @Parameters({ "browser" })
    @BeforeTest
    public static void setUpScenario(String browser) {
        BaseSteps.getInstance().getBrowserInstantiation(browser);
    }
} 

Note - I do have browser implementation method under BaseSteps Class. You can implement as per your need.

Step 2. Below is how we define parameter name and value in TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">

    <test thread-count="1" name="Test" parallel="classes">
        <parameter name="browser" value="chrome" />
        <classes>
            <class
                name="com.jacksparrow.automation.suite.runner.RunCukeTest" />
        </classes>
    </test>
</suite>

Upvotes: 0

Ency
Ency

Reputation: 633

Apparently, I can access to parameters from anywher usgin Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest().getParameter("browser")

Upvotes: 8

Related Questions