2

I have a cucumber project that uses spring boot and testng.

Here the principal classes

@SpringBootTest
public class CucumberTestDefinitions extends FunctionalTesting {

    @Given("Something")
    public void smthg(){

    }
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = FunctionalTestingApp.class, initializers =
        ConfigFileApplicationContextInitializer.class)
public class FunctionalTesting {

    @Autowired
    protected FunctionalTestingConfiguration configuration;
}
@EnableConfigurationProperties(value = {FunctionalTestingConfiguration.class})
public class FunctionalTestingApp  {
}
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "testing")
@Data
public class FunctionalTestingConfiguration {
// the config from yml file
}

I have no testng.xml file as tests are launched with spring-boot. For some reasons, I would like to prioritize tests and I saw I could do with QAF (https://qmetry.github.io/qaf/latest/scenario-meta-data.html#pre-defined-meta-data-for-bdd). I tried to use it but it didn't work.

Here what I did:

I added the dependency to pom.xml (I use cucumber 5)

I added this annotation @QAFTestStepProvider to CucumberTestDefinitions class

I added this plugin "com.qmetry.qaf.automation.cucumber.QAFCucumberPlugin" in RunnerTest class

Here the error

java.lang.NoSuchMethodError: 'java.lang.reflect.Method com.qmetry.qaf.automation.step.client.TestNGScenario.getMethod()'

I tried adding a testng.xml file in config folder but it didn't help

Is QAF spring-boot compatible?

Thanks a lot for helping

EDIT

pom.xml :

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>5.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-testng</artifactId>
            <version>5.6.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-spring</artifactId>
            <version>5.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.qmetry</groupId>
            <artifactId>qaf-cucumber</artifactId>
            <version>3.0.0</version>
        </dependency>
        
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>

The Runner class

        features = {"src/test/resources/toto"})
public class RunnerTest extends AbstractTestNGCucumberTests {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        return super.scenarios();
    }

    @PostConstruct
    public void setUp() {
        objectMapper.registerModule(new JavaTimeModule());
    }

}

error message

java.lang.NoSuchMethodError: 'java.lang.reflect.Method com.qmetry.qaf.automation.step.client.TestNGScenario.getMethod()'
    at com.qmetry.qaf.automation.step.client.TestNGScenario.init(TestNGScenario.java:92)
    at com.qmetry.qaf.automation.step.client.TestNGScenario.<init>(TestNGScenario.java:70)
    at com.qmetry.qaf.automation.step.client.TestNGScenario.<init>(TestNGScenario.java:64)
    at com.qmetry.qaf.automation.testng.TestRunnerFactory.convert(TestRunnerFactory.java:76)
    at com.qmetry.qaf.automation.testng.TestRunnerFactory.init(TestRunnerFactory.java:67)
    at com.qmetry.qaf.automation.testng.TestRunnerFactory.newTestRunner(TestRunnerFactory.java:63)
    at org.testng.ITestRunnerFactory.newTestRunner(ITestRunnerFactory.java:55)
    at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:676)
    at org.testng.SuiteRunner.init(SuiteRunner.java:178)
    at org.testng.SuiteRunner.<init>(SuiteRunner.java:112)
    at org.testng.TestNG.createSuiteRunner(TestNG.java:1275)
    at org.testng.TestNG.createSuiteRunners(TestNG.java:1251)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1100)
    at org.testng.TestNG.runSuites(TestNG.java:1039)
    at org.testng.TestNG.run(TestNG.java:1007)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
marie
  • 330
  • 5
  • 17
  • 1
    which version of qaf, qaf-cucumber, TestNG and cucumber you are using? can you also provide detailed error stacktrace? Can you share you runner class as well? – user861594 Sep 11 '20 at 17:35

1 Answers1

1

Unfortunately, i was not able to reproduce the same error and getting other errors regarding dependencies. However to address your original question "QAF cucumber testNG with spring boot" and aspect "like to prioritize tests" short answer is yes. But probably not both TESTNG and Cucumber runner together, especially prioritize tests. What does this mean?

When you are using cucumber suggested way for TestNG, it just creates one dummy test in TestNG and feeds scenarios as test data. Which will not capable to consider each scenario as independent TestNG test! so you won't be able to take all benefits from TestNG (for example, priority).

However, it doesn't mean that you can't can't achieve or can't use QAF+Cucmber+TestNG together. When you use QAF it has pure TestNG implementation for BDD. QAF considers each scenario as TestNG test and Scenario with examples (scenario outline) as data-driven test. qaf-cucuber will enable to use cucumber steps including dependency injection of your choice, Spring in your case. You will get benefit of all TestNG features including parallel execution, listeners and extended features from QAF like meta-data filter, test-data filter,

So when you want to use TestNG it is better to provide TestNG configuration to run your feature files written in BDD2 or Gherkin (subset of BDD2). All you need to do is create following XML file to run feature file written using BDD2 or Gherkin.

<suite name="QAF Demo" verbose="0">
<parameter name="step.provider.pkg" value="pkg.from.where.steps.needs.tobe.loaded" />
<parameter name="scenario.file.loc" value="src/test/resources/toto" />
<test name="BDD Test" enabled="true">
    <classes>
        <class name="com.qmetry.qaf.automation.step.client.text.BDDTestFactory2"></class>
    </classes>
</test>
</suite>

Note:

  • set step.provider.sharedinstance to true when using cucumber step implementation with class variables used in step.

  • In above way, as you are not using cucumber runner, so any cucumber hooks will not be executed. When you are using TestNG, it has better listener support that you can utilize and step listener you can use available with QAF. So if you have any hooks implemented you can move that in appropriate before/after listener methods and register listener in configuration file.


EDIT: I tried the test project which you shared, with it also i run into different issues. Finally i was able to figured it out as below.

POM updates:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.vaadin.external.google</groupId>
                    <artifactId>android-json</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.10</version>
            <scope>test</scope>
        </dependency>

You have two choices. Using BDD2 Factory which creates TestNGScenario for each scenario or the cucumber runner way. In either case it should work. You can add reporting dashboard to view reports after execution.

Option-1: pure Testng

Create config file to run as pure Testng test using BDDTestFactory2:

<suite name="QAF Demo" verbose="0">
    <parameter name="step.provider.pkg" value="my.custom.packagename.testing"/>
    <parameter name="scenario.file.loc" value="src/test/resources/my/custom/packagename/testing"/>
    <parameter name="step.provider.sharedinstance" value="true" />
    <test name="BDD Test" enabled="true">
        <classes>
            <class name="com.qmetry.qaf.automation.step.client.text.BDDTestFactory2"></class>
        </classes>
    </test>
</suite>

Use this config file instead of your runner class. In this case you don't required cucumber-testng dependency.

Option-2: cucumber runner for Testng

  • you will required cucumber-testng dependency
  • To run using your cucumber runner use same version for cucumber and cucumber testng. In your case cucumber-* version needs to be same either 5.6.0 or 5.4.0
  • Update runner class as below:
@CucumberOptions(plugin = {"com.qmetry.qaf.automation.cucumber.QAFCucumberPlugin", "pretty", "html:target", "timeline:target"},
        /*tags = {"@Ignore"},*/
        features = {"src/test/resources/my/custom/packagename/testing"})
public class RunnerTest extends AbstractTestNGCucumberTests {

    @Autowired
    private ObjectMapper objectMapper;
    
    @Test(groups = "cucumber", description = "Runs Cucumber Scenarios", dataProvider = "scenarios")
    public void runScenario(PickleWrapper pickleWrapper, FeatureWrapper featureWrapper) throws Throwable {
        super.runScenario(pickleWrapper,featureWrapper);
    }

    @Override
    @DataProvider(parallel = true, name = "scenarios")
    public Object[][] scenarios() {
        return super.scenarios();
    }

    @PostConstruct
    public void setUp() {
        objectMapper.registerModule(new JavaTimeModule());
    }

}

Run as TestNG.

user861594
  • 4,526
  • 3
  • 23
  • 39
  • Thanks for helping, I created a github repo that reproduces the error https://github.com/marcesso/qafTesting. The issue may be a simple missing file or a wrong file path – marie Sep 15 '20 at 08:56
  • thanks for the update, I will try soon and let your know – marie Oct 02 '20 at 07:12
  • It worked as expected, thanks a lot. I used the option 2, the issues were mixed versions of cucumber dependencies, missing cucumber-testng dependency in pom and the missing @Test method in RunnerTest.class – marie Oct 05 '20 at 09:14