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:

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:

[java]
[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
===============================================

[/java]

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:

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");
	}
	
	
}

[java]
[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
===============================================

[/java]

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

Leave a Reply

Your email address will not be published. Required fields are marked *