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
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments