TestNG Tutorials 62: Dependency in TestNG – Types of Dependencies in TestNG – Hard Dependency & Soft Dependency
We have learnt in previous posts regarding establishing relationship between test methods. You can go through them below:
Dependency in TestNG – Creating Dependency Among Test Methods – DependsOnMethod
Dependency in TestNG – Creating Dependency Among Test Methods – DependsOnGroup
Before we learn about types of dependencies in TestNG, lets see one scenario first:
If my method say Test1 depends on another method say Test2 and it fails.
Test2 will not run as its dependent method Test1 is failed. Remember here that Test2 will not be marked as Failed. It will be marked as Skipped and A skipped test is not actually a failed test.
See example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package Dependecy; import org.testng.Assert; import org.testng.annotations.Test; public class HardDependeny { // Explicitly failing method on which Test2 is dependent @Test public void Test1() { System.out.println("I am Test1"); Assert.fail(); } // Test2 will not run as Test1 has failed. Test2 will be marked as skipped. @Test(dependsOnMethods= {"Test1"}) public void Test2() { System.out.println("I am Test2"); } } |
Output:
[RemoteTestNG] detected TestNG version 6.14.2 I am Test1 FAILED: Test1 java.lang.AssertionError: null at org.testng.Assert.fail(Assert.java:96) at org.testng.Assert.fail(Assert.java:103) at Dependecy.HardDependeny.Test1(HardDependeny.java:15) 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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124) at org.testng.internal.Invoker.invokeMethod(Invoker.java:580) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org.testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) SKIPPED: Test2 java.lang.Throwable: Method HardDependeny.Test2()[pri:0, instance:Dependecy.HardDependeny@215be6bb] depends on not successfully finished methods at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:887) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org.testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) =============================================== Default test Tests run: 2, Failures: 1, Skips: 1 =============================================== =============================================== Default suite Total tests run: 2, Failures: 1, Skips: 1 ===============================================
Same thing happens with dependsOnGroups as well. If any method of mentioned dependent group/groups is failed, it will not run.
Actually above dependency is called Hard Dependency. If any dependent method is failed, any method dependent on that method will be skipped.
Another type of dependency is called Soft Dependency. If you want that your method should not marked as Skip if dependent methods are failed, you need to add an attribute called “alwaysRun” as true. It will run your method even if dependent method is failed. This is useful when you just want to make sure that your test methods are run in a certain order but their success doesn’t really depend on the success of others.
An example is below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package Dependecy; import org.testng.Assert; import org.testng.annotations.Test; public class HardDependeny { // Explicitly failing method on which Test2 is dependent @Test public void Test1() { System.out.println("I am Test1"); Assert.fail(); } // Test2 will not run as Test1 has failed. Test2 will be marked as skipped. @Test(dependsOnMethods= {"Test1"}, alwaysRun= true) public void Test2() { System.out.println("I am Test2"); } } |
[RemoteTestNG] detected TestNG version 6.14.2 I am Test1 I am Test2 PASSED: Test2 FAILED: Test1 java.lang.AssertionError: null at org.testng.Assert.fail(Assert.java:96) at org.testng.Assert.fail(Assert.java:103) at Dependecy.HardDependeny.Test1(HardDependeny.java:15) 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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124) at org.testng.internal.Invoker.invokeMethod(Invoker.java:580) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org.testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) =============================================== Default test Tests run: 2, Failures: 1, Skips: 0 =============================================== =============================================== Default suite Total tests run: 2, Failures: 1, Skips: 0 ===============================================
You can see Test2 executed even its dependent method Test1 is failed.
So to summarize above points:
There are two types of dependencies in TestNG:
1. Hard Dependency : All the methods you depend on must have run and succeeded for you to run. If at least one failure occurred in your dependencies, you will not be invoked and marked as a SKIP in the report.
2. Soft Dependency : You will always be run after the methods you depend on, even if some of them have failed. This is useful when you just want to make sure that your test methods are run in a certain order but their success doesn’t really depend on the success of others. A soft dependency is obtained by adding “alwaysRun=true” in your @Test annotation.
If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappySelenium
Author: Amod Mahajan
A software Tester who is paid to judge products developed by others. Currently getting paid in American Dollars. Writing technical posts and creating YouTube videos are my hobbies.