Sometimes we want our test cases to run in specific order. One of the very common examples is when we want to run test cases for CRUD operations. So we want to make sure that test data is inserted first, then it’s retrieved, updated and finally deleted.
Table of Contents
TestNG Dependency Example – dependsOnMethods
Let’s say we have a test class for CRUD operations.
package com.journaldev.dependency;
import org.testng.annotations.Test;
public class TestNGDependencyExample {
@Test
public void insert() {
System.out.println("inserting demo data");
}
@Test
public void select() {
System.out.println("selecting demo data");
}
@Test
public void update() {
System.out.println("updating demo data");
}
@Test
public void delete() {
System.out.println("deleting demo data");
}
}
Since there is no order defined by us, TestNG will execute them in the natural order of their names. So when we run test class, we will get following output.
deleting demo data
inserting demo data
selecting demo data
updating demo data
This is not what we want our test cases order to be. One of the quick and dirty ways is to change the method names so that they get executed in the order we want them to.
The better way is to use dependsOnMethods
to tell TestNG which methods this test is dependent on, so those methods should be executed before this method.
Below is our updated test class where we are creating the order of execution – insert, select, update and delete.
package com.journaldev.dependency;
import org.testng.annotations.Test;
public class TestNGDependencyExample {
@Test
public void insert() {
System.out.println("inserting demo data");
}
@Test(dependsOnMethods="insert")
public void select() {
System.out.println("selecting demo data");
}
@Test(dependsOnMethods="select")
public void update() {
System.out.println("updating demo data");
}
@Test(dependsOnMethods="update")
public void delete() {
System.out.println("deleting demo data");
}
}
The new output of test run is:
inserting demo data
selecting demo data
updating demo data
deleting demo data
dependsOnMethods
takes String array as argument. Below annotation on delete() method is also fine and produces the same result.
@Test(dependsOnMethods= {"insert","update"})
public void delete() {
System.out.println("deleting demo data");
}
TestNG Dependency Tests – dependsOnGroups
We can also specify if our test depends on any other groups. This is helpful when we have multiple methods and they are grouped together. So we can simply specify the group this test depends on, rather than specifying the huge list of all the methods.
Let’s look at a little bit complex example where our tests are dependent on methods as well as groups. All the earlier defined methods are part of the group named “tests”. These methods depend on “pre-tests” group. We also have a cleanup method that depends on the “tests” group.
package com.journaldev.dependency;
import org.testng.annotations.Test;
public class TestNGDependencyExample {
@Test(groups = "pre-tests")
public void init() {
System.out.println("init resources");
}
@Test(groups = "tests", dependsOnGroups = "pre-tests")
public void insert() {
System.out.println("inserting demo data");
}
@Test(dependsOnMethods = "insert", groups = "tests")
public void select() {
System.out.println("selecting demo data");
}
@Test(dependsOnMethods = "select", groups = "tests")
public void update() {
System.out.println("updating demo data");
}
@Test(dependsOnMethods = { "insert", "update" }, groups = "tests")
public void delete() {
System.out.println("deleting demo data");
}
@Test(dependsOnGroups = "tests")
public void cleanup() {
System.out.println("closing resources");
}
}
The output of test execution is:
init resources
inserting demo data
selecting demo data
updating demo data
deleting demo data
closing resources
TestNG Dependency in XML Suite
TestNG XML suite allows us to define dependencies between groups. If we have to define the methods invocation order then we can use invocation-numbers
for methods element.
Let’s say we have a new class with almost same methods as earlier, but there is no dependency defined between methods and groups.
package com.journaldev.dependency;
import org.testng.annotations.Test;
public class TestNGDependencyXMLExample {
@Test(groups = "pre-tests")
public void init() {
System.out.println("init resources");
}
@Test(groups = "tests")
public void insert() {
System.out.println("inserting demo data");
}
@Test(groups = "tests")
public void select() {
System.out.println("selecting demo data");
}
@Test(groups = "tests")
public void update() {
System.out.println("updating demo data");
}
@Test(groups = "tests")
public void delete() {
System.out.println("deleting demo data");
}
@Test(groups = "post-tests")
public void cleanup() {
System.out.println("closing resources");
}
}
Here is our TestNG XML suite that will define the order of execution of groups and methods.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestNG XML Dependency Test Suite" time-out="300">
<test name="TestNGXML Dependency Test" verbose="2" time-out="500">
<groups>
<dependencies>
<group depends-on="pre-tests" name="tests"></group>
<group depends-on="tests" name="post-tests"></group>
</dependencies>
</groups>
<classes>
<class
name="com.journaldev.dependency.TestNGDependencyXMLExample">
<methods>
<include name="init"></include>
<include name="cleanup"></include>
<include name="insert" invocation-numbers="1"></include>
<include name="select" invocation-numbers="2"></include>
<include name="update" invocation-numbers="3"></include>
<include name="delete" invocation-numbers="4"></include>
</methods>
</class>
</classes>
</test>
</suite>
Summary
We looked into creating order of execution of test methods and groups using dependsOnMethods
and dependsOnGroups
properties of Test annotation. We also learned how to achieve the same thing in XML suite file.
This is good. but I can not run individual tests. For that again I have to give dependOnGroup for each of the tests. Is there any alternative?