Search code examples
javaseleniumtestngbddqaf

QAF | If dependent scenario fails, running scenario should skip


Does QAF support the Dependent Scenario option out of the box? I have read in the below link that dependsOnMethods is not working and not supported.

https://github.com/qmetry/qaf/issues/281

If the dependent scenario option is not available in QAF out of the box, can we write a custom function to check the dependent scenario result and Skip the executing scenario if the dependent scenario has failed? Any past posts or guidance will be very helpful.

Note: I'm using BDDTestFactory2.

###################### UPDATED ######################

Tried below code in testng listner, but it is not skipping the test.

@Override
    public void onTestStart(ITestResult result) {
        if (dependentTc == "fail") {
            resultOperation(result, "skipped");
            throw new SkipException("################# Testing skip - Triggered. #################");

        }
}

Below are from console log:

org.testng.SkipException: ################# Testing skip - Triggered. #################
        at com.rt.listener.rt_listener.onTestStart(rt_listener.java:117)
        at org.testng.internal.Invoker.runTestListeners(Invoker.java:1724)
        at org.testng.internal.Invoker.runTestListeners(Invoker.java:1699)
        at org.testng.internal.Invoker.invokeMethod(Invoker.java:622)
        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)
        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)
        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
        at org.testng.TestRunner.privateRun(TestRunner.java:756)
        at org.testng.TestRunner.run(TestRunner.java:610)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
        at org.testng.SuiteRunner.run(SuiteRunner.java:289)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
        at org.testng.TestNG.runSuites(TestNG.java:1133)
        at org.testng.TestNG.run(TestNG.java:1104)
        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:122)
        at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92)
        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
        at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
        at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)

Solution

  • Test dependency is supported for test/scenario written in java with QAF.

    Having dependency between scenarios in BDD is not a good idea, one of the possible way is, set flag in after method and check flag in before method using testng listener. Let say scenario-2 is dependent on scenario-1,

    • make sure the order in you feature file is correct
    • in after method check if test name or metadata is scenario-1 and status is fail, set flag let say my-precondition to false.
    • in before method check if test name or metadata is scenario-2 and my-precondition is false, throw SkipExeption.

    Above approach may have possible side-effects as well.

    If you want to take benefit of test dependency along with BDD, it is supported with RuntimeScenarioFactory. The good part of it is, it doesn't required separate feature file. If you required to have feature file for any reason you can generate feature files using Behavior Generator. Furthermore, with RuntimeScenarioFactory you can have more programing control then scenario in feature file.

    You also can have combination of tests in feature file (scenarios) as well as test in java file(using RuntimeScenarioFactory). Both has same capabilities for example: detailed reporting, dry run, data-driven, meta-data, meta-data filter etc.

    EDIT: Below example worked fine for me.

    Example feature file:

    @smoke
    Feature: scenario with dependency
    
    @TestCaseId:Test-111
    Scenario: scenario1
        Given COMMENT: "some situation"
        When process data
        Then verify update address response with {'addr1':'123 main st'}
        
    @dependsOnMethods:['scenario1']
    @TestCaseId:Test-112
    Scenario: scenario2
        Given COMMENT: "some situation"
        When COMMENT: "some_action_performed"
        Then COMMENT: "it_should_have_some_behavior"
    
    

    Example listener that will skip scenario if one scenario(s) failed on which is depends upon.

    package qaf.example.listener;
    ...
    public class DependecyListener implements ITestListener{
        
        @Override
        public void onTestStart(ITestResult result) {
            ITestNGMethod method = result.getMethod();
            String[] methodsDependedUpon = method.getMethodsDependedUpon();
            if (method.isTest() && null != methodsDependedUpon && methodsDependedUpon.length > 0) {
                List<String> methodsDependedUponLst = Arrays.asList(methodsDependedUpon);
                IResultMap failedTests = result.getTestContext().getFailedTests();
                List<ITestResult> falildMethodsDependedUpon = failedTests.getAllResults().stream()
                        .filter(t -> methodsDependedUponLst.contains(t.getName())).collect(Collectors.toList());
                if(!falildMethodsDependedUpon.isEmpty()) {
                    throw new SkipException("Skipped because of dependency failure!");
                }
            }
        }
    }
    

    Add listener in your xml configuration file>

        <listeners>
            <listener class-name="qaf.example.listener.DependecyListener" />
        </listeners>