TestNG timeOut example

In this post we will learn how to configure TestNG Tests to timeout after certain time, using TestNG timeout feature with help of @Test(timeOut = 1000). A @Test is supposed to complete its execution within very short time. In case a @Test is taking unreasonably long-time than expected, it’s something to investigate. In those situations, we can run that @Test with applying a timeout(in milliSeconds) like @Test(timeOut = 1000). With this way, if the test does not complete it’s execution within applied timeout, it will fail. Let’s get going.


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

package com.websystique.testng;

public class Calculator {

	public double add(double a, double b){
		return a+b;
	}
	
	public double subtract(double a, double b) throws InterruptedException{
		Thread.sleep(5000);
		return a-b;
	}
	
}

For demonstration purpose, we have included Thread.sleep(5000) in subtract method. That means subtract method will take little more than 5000 milliseconds to complete it’s executions.

Let’s write a trivial test class with two test methods add & subtract.

package com.websystique.testng;

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

public class TestNGTimeOutExample {

	Calculator calculator;

	@BeforeClass
	public void setup() {
		System.out.println("setup()");
		calculator = new Calculator();
	}

	@AfterClass
	public void tearDown() {
		System.out.println("tearDown()");
		calculator = null;
	}

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

	@AfterMethod
	public void afterMethod() {
		System.out.println("afterMethod()");
	}

	@Test
	public void testAdd() {
		System.out.println("testAdd()");
		Assert.assertEquals(calculator.add(3, 4), 7.0);
	}

	@Test(timeOut = 3000)//timeout in milliseconds
	public void testSubtract() throws InterruptedException {
		System.out.println("testSubtract()");
		Assert.assertEquals(calculator.subtract(5, 2), 3.0);
	}

}

We have also included the @BeforeClass & @BeforeMethod to see the overall effect.

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

setup()
beforeMethod()
testAdd()
afterMethod()
beforeMethod()
testSubtract()
afterMethod()
tearDown()
PASSED: testAdd
FAILED: testSubtract
org.testng.internal.thread.ThreadTimeoutException: Method org.testng.internal.TestNGMethod.testSubtract() didn't finish within the time-out 3000
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.doSignalAll(AbstractQueuedSynchronizer.java:1890)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1959)
	at java.util.concurrent.ThreadPoolExecutor.tryTerminate(ThreadPoolExecutor.java:707)
	at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1006)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1163)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)


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

You can see that @Test method for subtract failed as it took more than 3 seconds(timeout limit) to finish it’s execution.

Additional noticeable points are :

  • @BeforeClass/@AfterClass was called as there is at least one @Test method in this class which got executedI. In our case both were executed.
  • @BeforeMethod/@AfterMethod was called for both methods. Even if subtract @Test failed, it was nonetheless executed, so @BeforeMethod/@AfterMethod was called for this as well.

That’s it.

References