TestNG dependsOnMethods Example

In this post we will see TestNG dependency example between different test methods using @Test annotation’s dependsOnMethods and alwaysRun attributes.

A very simple and real life use case [where these attributes can be handy] is user update operations e.g. In order to update a user, it must be created at first place. So while writing tests, you can write both createUser and updateUser tests, make updateUser depends on createUser, and execute updateUser if and only if the createUser executed successfully. Let’s get going.


dependsOnMethods : dependsOnMethods attribute on a test method [test1 e.g.] specifies all the test methods [test2, test3,..] this test method depends on. It means test1 will start execution only after all the tests it depends on executed successfully. If any of the tests specified via dependsOnMethods attribute failed, then test1 will be skipped.

alwaysRun=true : Setting alwaysRun attribute on a test method to true forces the execution of this test even if the tests it depends on were failed.


Let’s take a simple Calculator class to demonstrate this feature.

package com.websystique.testng;

public class Calculator {

	public int add(int a, int b){
		return a+b;
	}

	public int divide(int a, int b){
		return a/b;
	}

}

It’s evident that divide method will throw ArithmaticException if b is 0.

Let’s write a trivial test class.

package com.websystique.testng;

import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestNGDependsOnMethodsExample {

	@BeforeMethod
	public void beforeMethod() {
		System.out.println("beforeMethod()");
	}

	@AfterMethod
	public void afterMethod() {
		System.out.println("afterMethod()\n");
	}
	
	@Test
	public void testAdd() {
		System.out.println("testAdd()");
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.add(15, 2) , 17);
	}

	@Test
	public void testDivide() {
		System.out.println("testDivide()");
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.divide(16, 0), 16);
	}
	
	@Test(dependsOnMethods={"testAdd", "testDivide"})
	public void testProcessRealNumbers() {
		System.out.println("testProcessRealNumbers()");
	}

	@Test(dependsOnMethods={"testAdd", "testDivide"}, alwaysRun=true)
	public void testProcessEvenNumbers() {
		System.out.println("testProcessEvenNumbers()");
	}

}

Clearly, testAdd will be executed fine. But testDevide will throw an ArithmaticException as we are dividing by 0. This will cause testDivide to fail.

Run above test class using TestNG Eclipse plugin or maven (mvn clean test). Following is the outcome:

beforeMethod()
testAdd()
afterMethod()

beforeMethod()
testDivide()
afterMethod()

beforeMethod()
testProcessEvenNumbers()
afterMethod()

PASSED: testAdd
PASSED: testProcessEvenNumbers
FAILED: testDivide
java.lang.ArithmeticException: / by zero
	at com.websystique.testng.Calculator.divide(Calculator.java:10)
	at com.websystique.testng.TestNGDependsOnMethodsExample.testDivide(TestNGDependsOnMethodsExample.java:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

SKIPPED: testProcessRealNumbers

===============================================
    Default test
    Tests run: 4, Failures: 1, Skips: 1
===============================================

It’s clear from above output that testProcessRealNumbers was skipped as one of the method it depends on (testDivide) failed.

Method testProcessEvenNumbers, however was still executed, thanks to alwaysRun=true.

That’s it.

References