Create dependent automation scripts with Test NG



There are situations when you need your test automation scripts to run in a specific order.

For example, if you are automating user scenarios for an ecommerce site, you may have test scripts such as

searchForProduct() - tests if there are valid products on the site

addProductToCart() - tests if products can be added to the cart

checkoutAndPay() - test that the checkout process works correctly

It is possible that sometimes the site does not have valid products available.

Without valid products, nothing can be added to the cart.

So if the searchForProduct() test script fails because there are no valid products available, there is no point executing the other 2 test scripts.

In this case, searchForProduct() fails and addProductToCart() and checkoutAndPay() should be skipped.


How can you have dependent test scripts in JUNIT?



JUNIT does not have good support for running test scripts in a specific order.

You can use @FixMethodOrder(MethodSorters.NAME_ASCENDING) for running the test scripts in the ascending name order.

And this is about everything that you can do.



How can you have dependent test scripts in TestNG?


Going back to the example already discussed, we have a test class with 3 test scripts:

package tests;

import org.testng.annotations.Test;

public class RandomCheckOutTests {

@Test
public void checkOutAndPay()
{
  System.out.println("3. checkOutAndPay Completed ");
}

@Test
public void addProductToCart()
{
  System.out.println("2. addProductToCart Completed");
}

@Test
public void searchForProduct()
{

  System.out.println("1. searchForProduct Completed");

}
 
}

Running the test class generates the following result:

[TestNG] Running:
C:\Users\asiminiuc\AppData\Local\Temp\testng-eclipse--2137197999\testng-customsuite.xml


2. addProductToCart Completed
3. checkOutAndPay Completed
1. searchForProduct Completed
PASSED: addProductToCart
PASSED: checkOutAndPay
PASSED: searchForProduct


===============================================
Default test
Tests run: 3, Failures: 0, Skips: 0
===============================================


By default, the test scripts are executed in a random order.
addProductToCart() runs before searchForProduct().

Lets see what happens if the searchForProduct() script fails:

package tests;

import static org.testng.AssertJUnit.assertTrue;
import org.testng.annotations.Test;

public class RandomCheckOutTests {

@Test
public void checkOutAndPay()
{
  System.out.println("3. checkOutAndPay Completed ");
}
 
@Test
public void addProductToCart()
{
  System.out.println("2. addProductToCart Completed");
}

@Test
public void searchForProduct()
{

  System.out.println("1. searchForProduct Completed");

  assertTrue(false);

}
 
}


The results of executing the test scripts are:

[TestNG] Running:
C:\Users\asiminiuc\AppData\Local\Temp\testng-eclipse--1193208089\testng-customsuite.xml


2. addProductToCart Completed
3. checkOutAndPay Completed
1. searchForProduct Completed
PASSED: addProductToCart
PASSED: checkOutAndPay
FAILED: searchForProduct

===============================================
Default test
Tests run: 3, Failures: 1, Skips: 0
===============================================


searchForProduct() fails and addProductToCart() and checkoutAndPay() are executed as well.

This does not make sense.

If searchForProduct() fails, addProductToCart() and checkOutAndPay() should be ignored.

We need to make addProductToCart() and checkOutAndPay() dependent on the sucess or failure of searchForProduct().

To make the scripts dependent, we need to use the dependsOnMethods or dependsOnGroups annotations:

package tests;

import org.testng.annotations.Test;

public class OrderedCheckOutTests {

@Test (dependsOnMethods = "addProductToCart")
public void checkOutAndPay()
{
  System.out.println("3. checkOutAndPay Completed ");  
}
 
@Test (dependsOnMethods = "searchForProduct")
public void addProductToCart()
{
 System.out.println("2. addProductToCart Completed");
}

@Test
public void searchForProduct()
{
 System.out.println("1. searchForProduct Completed");
}
}

In this case, addProductOnCart() depends on searchForProduct().
searchForProduct() will run before addProductOnCart().

checkOutAndPay() depends on addProductToCart().
addProductToCart() will run before checkOutAndPay().


This is the result of running the test scripts:

[TestNG] Running:
C:\Users\asiminiuc\AppData\Local\Temp\testng-eclipse-1181658048\testng-customsuite.xml

1. searchForProduct Completed
2. addProductToCart Completed
3. checkOutAndPay Completed
PASSED: searchForProduct
PASSED: addProductToCart
PASSED: checkOutAndPay

===============================================
Default test
Tests run: 3, Failures: 0, Skips: 0
===============================================


The scripts will always run in the following order:

searchForProduct
addProductToCart
checkOutAndPay



What if one of the test scripts fails?


I will make the searchForProduct() script fail with an assertion:

package tests;

import static org.testng.AssertJUnit.assertTrue;
import org.testng.annotations.Test;

public class OrderedCheckOutTests {

@Test (dependsOnMethods = "addProductToCart")
public void checkOutAndPay()
{
  System.out.println("3. checkOutAndPay Completed ");  
}

@Test (dependsOnMethods = "searchForProduct")
public void addProductToCart()
{
  System.out.println("2. addProductToCart Completed");
}
 
@Test
public void searchForProduct()
{
  System.out.println("1. searchForProduct Completed");

  assertTrue(false);
}

}


When the test scripts are executed again, searchForProduct fails and the other 2 test scripts are skipped:

[TestNG] Running:
C:\Users\asiminiuc\AppData\Local\Temp\testng-eclipse-349769629\testng-customsuite.xml

1. searchForProduct Completed
FAILED: searchForProduct
java.lang.AssertionError:

SKIPPED: addProductToCart
java.lang.Throwable: Method OrderedCheckOutTests.addProductToCart()[pri:0, instance:tests.OrderedCheckOutTests@71e7a66b] depends on not successfully finished methods


SKIPPED: checkOutAndPay
java.lang.Throwable: Method OrderedCheckOutTests.checkOutAndPay()[pri:0, instance:tests.OrderedCheckOutTests@71e7a66b] depends on not successfully finished methods

===============================================
Default test
Tests run: 3, Failures: 1, Skips: 2
===============================================




Is this the only way for having dependent test scripts?

DependsOnMethods is just one of the ways of making test scripts dependent.

The other method is DependOnGroups:

package tests;

import org.testng.annotations.Test;

public class OrderedCheckOutTests2 {

@Test (dependsOnGroups = "search")
public void checkOutAndPay()
{
  System.out.println("3. checkOutAndPay Completed ");  
}

@Test (groups = "search")
public void addProductToCart()
{
  System.out.println("2. addProductToCart Completed");
}

@Test (groups = "search")
public void searchForProduct()
{
  System.out.println("1. searchForProduct Completed");  
}

}


Before the checkOutAndPay script runs, the scripts from the search groups are executed.

The scripts from the group are executed in a random order.


READ NEXT: 
Why is unit testing essential for test automation?

Share this

4 Responses to "Create dependent automation scripts with Test NG"

  1. Beautiful... i was not knowing dependsOnGroups ... thanks for the post...

    ReplyDelete
  2. Thank you :).... Did not know about dependsOn functionality!

    ReplyDelete