TestNG Showcase – Unit Test Dependencies

A nice feature of TestNG that JUnit 4 is missing is the fact that it’s possible to specify unit tests that rely on other unit tests to complete first.

An example:

package com.dimitrisli.testng.dependents;

import org.testng.annotations.Test;

public class DependentMethodTesting {

	@Test(dependsOnMethods={"method1"})
	public void method2(){
		System.out.println("hi I am method2 and I depend on method1");
	}
	
	@Test
	public void method1(){
		System.out.println("hi I am method1");
	}
}

that produces the output:

hi I am method1
hi I am method2 and I depend on method1

The code can be found in this Github repository.

TestNG Showcase – Parameterized Testing

The parameterized functionality is very helpful when it comes to group repetitive code for different input data.

We can do the following if we wanted to inject a parameter from a config file:

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="My parameterized test suite">
  <test name="parameterised injection testing">
 
    <parameter name="i" value="13"/> 	
 
    <classes>
       <class name="com.dimitrisli.testng.parameterized.ParameterizedInjectionTest" />
    </classes>
  </test>
</suite>

to a unit test:

package com.dimitrisli.testng.parameterized;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class ParameterizedInjectionTest {

	@Test
	@Parameters(value="i")
	public void method1(int i){
		System.out.println("inside method1() of parameterized example injected i = "+i);
	}
}

@DataProvider is similar to JUnit 4’s @Parameters to inject values en masses, a trivial example would look like so:

package com.dimitrisli.testng.parameterized;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class DataProviderTesting {

	@DataProvider(name="dataProviderMethod")
	public Object[][] parameterMethod(){
		return new Object[][]{{"one",1},{"two",2}};
	}
	
	@Test(dataProvider="dataProviderMethod")
	public void testMethod(String str, int val){
		System.out.println("str="+str+", val="+val);
	}
}

A nice variation is to pass proper Java beans around:

package com.dimitrisli.testng.parameterized;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class AdvancedParameterizedTesting {

	public static class Bean{
		private String val;
		private int i;
		
		public Bean(String val, int i){
			this.val=val;
			this.i=i;
		}
		
		public String getStr(){
			return this.val;
		}
		
		public int getInt(){
			return this.i;
		}
		
	}
	
	@DataProvider(name = "advancedParameterizedMethod")
	public Object[][] advancedParameterizedMethod(){
		return new Object[][]{{new Bean("hi I am the bean",111)}};
	}
	
	@Test(dataProvider="advancedParameterizedMethod")
	public void testMethod(Bean myBean){
		System.out.println(myBean.getStr()+" "+myBean.getInt());
	}
}

The source code could be found in this Github repository.

TestNG Showcase – Groups

Groups is a very nice versatile functionality that JUnit 4 is still missing. TestNG gives you the flexibility through specified groups to gather up and run buckets of unit tests grouped in their own separate scenarios. Someone could group for instance integration tests, database related tests, framework tests, the possibilities are endless.

In our example we would need a TestNG XML config file first, making all the necessary introductions:

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="Groups Suite">
  <test name="groups suite test">
  	<groups>
      <run>
        <include name="group2"/>
        <include name="group3"/>
      </run>
    </groups>
    <classes>
       <class name="com.dimitrisli.testng.groups.TestNGGroupsTesting" />
    </classes>
  </test>
</suite>

The referenced TestNG Class looks like this:

package com.dimitrisli.testng.groups;

import org.testng.annotations.Test;

public class TestNGGroupsTesting {

	@Test(groups="group3")
	public void method1(){
		System.out.println("inside method1 of group 3");
	}
	
	@Test(groups="group1")
	public void method2(){
		System.out.println("inside method2 of group 1");
	}
	
	@Test(groups="group2")
	public void method3(){
		System.out.println("inside method3 of group 2");
	}
	
	@Test(groups="group2")
	public void method4(){
		System.out.println("inside method4 of group 2");
	}
	
	@Test(groups="group1")
	public void method5(){
		System.out.println("inside method5 of group 1");
	}
}

Running just that class as a TestNG test would yield:

inside method1 of group 3
inside method2 of group 1
inside method3 of group 2
inside method4 of group 2
inside method5 of group 1
PASSED: method1
PASSED: method2
PASSED: method3
PASSED: method4
PASSED: method5

which are all the unit tests in order of appearance. This is because we didn’t take yet the xml config file into consideration. Since we are using Maven as a building tool specifying the config file takes place in the maven Surefire TestNG-enabled plugin that looks like this:

<plugin>
  			<groupId>org.apache.maven.plugins</groupId>
  			<artifactId>maven-surefire-plugin</artifactId>
  			<version>2.11</version>
  			<configuration>
  				<suiteXmlFiles>
  					
  					<suiteXmlFile>testngGroups.xml</suiteXmlFile>
  					
  				</suiteXmlFiles>
  			</configuration>
  		</plugin>

We’ve just shaped the testing phase of Maven to consider the TestNG groups in this special manner. Running mvn package produces the following among the output:

inside method1 of group 3
inside method3 of group 2
inside method4 of group 2

which is the grouping in the order we desired and have specified in the config file.

An interesting alternative or override is the Surefire plugins configuration to assist group references within the POM:

<plugin>
  			<groupId>org.apache.maven.plugins</groupId>
  			<artifactId>maven-surefire-plugin</artifactId>
  			<version>2.11</version>
  			<configuration>
  				<suiteXmlFiles>
  					
  					<suiteXmlFile>testngGroups.xml</suiteXmlFile>
  					
  				</suiteXmlFiles>
<groups>group2</groups>
  			</configuration>
  		</plugin>

If we do so, then we override the grouping specified in the config file having as output this time:

inside method3 of group 2
inside method4 of group 2

You can find this code in this Github repository.

TestNG Showcasing – Suites

Although supported in JUnit 4, in the earlier JUnit 3 it was only TestNG that made the Suites hierarchy possible.

To gather the specifics of Suites we would need a config xml file that for our case would look like:

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="Suites test">
  <test name="testingSuites">
    <classes>
       <class name="com.dimitrisli.testng.suite.TestNGSuiteClass2" />
       <class name="com.dimitrisli.testng.suite.TestNGSuiteClass1" />
    </classes>
  </test>
</suite>

Since we are using Maven as our build management tool, it’s good to know that the Surefire plugin is TestNG-enabled needing the following structure to specify the TestNG related config file:

<plugin>
  			<groupId>org.apache.maven.plugins</groupId>
  			<artifactId>maven-surefire-plugin</artifactId>
  			<version>2.11</version>
  			<configuration>
  				<suiteXmlFiles>
  					<suiteXmlFile>testng.xml</suiteXmlFile>
  				</suiteXmlFiles>
  				</configuration>
  		</plugin>

For our example we have two test Classes:

package com.dimitrisli.testng.suite;

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

public class TestNGSuiteClass1 {

	@Test
	public void method1(){
		System.out.println("From TestNGSuiteClass1 test case");
		Assert.assertTrue(true);
	}
}

and

package com.dimitrisli.testng.suite;

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

public class TestNGSuiteClass2 {

	@Test
	public void method1(){
		System.out.println("From TestNGSuiteClass2 test case");
		Assert.assertTrue(true);
	}
}

After executing mvn package we notice the following in the output:

Running TestSuite
From TestNGSuiteClass2 test case
From TestNGSuiteClass1 test case

We have just intervened in the Maven build lifecycle enhancing the test phase to consider our TestNG suite and to run the unit tests accordingly.

You can find this code in this Github repository

TestNG Showcase – Exceptions Testing

Similar to JUnit 4 testing, TestNG is providing functionality to check exceptions are thrown when we are expecting them to be thrown.

A simple example:


package com.dimitrisli.testng.exceptionTesting;

import org.testng.annotations.Test;


public class ExceptionsTesting {

	@Test(expectedExceptions = NullPointerException.class)
	public void method(){
		throw new NullPointerException();
	}

	@Test(expectedExceptions = IllegalArgumentException.class)
	public void method2(){
		throw new IllegalArgumentException();
	}
}

The overall code concerning the TestNG showcasing can be found in this Github repository.

TestNG Showcase – Performance testing

Similar to JUnit 4, TestNG is providing means for performance measurements.

An example:

package com.dimitrisli.testng.performance;

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



public class PerformanceTesting {

	@Test(timeOut=100)
	public void method(){
		Assert.assertTrue(true);
	}
}

You can find the overall code of the TestNG showcasing in this Github repository.

TestNG Showcase – Before and After

Similar to JUnit 4, TestNG is providing similar Before and After functionalities with the addition of @BeforeSuite and @AfterSuite. Also instead of @Before and @After as it is named in JUnit (before and after each unit test) it is now named @BeforeMethod and @AfterMethod providing though identical functionality.

An example:

package com.dimitrisli.testng.beforeAfter;

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


public class TestNGBeforeAfterTesting {

	@BeforeSuite
	public static void initialiseSuite(){
		System.out.println("init suite");
	}

	@BeforeClass
	public static void initialiseClass(){
		System.out.println("init class");
	}
	
	@BeforeMethod
	public void initialiseTest(){
		System.out.println("init test");
	}
	
	@Test
	public void test1(){
		System.out.println("inside test1");
		Assert.assertTrue(true);
	}

	@Test
	public void test2(){
		System.out.println("inside test2");
		Assert.assertTrue(true);
	}
	
	@AfterMethod
	public void teardownTest(){
		System.out.println("teardown test");
	}
	
	@AfterClass
	public static void teardownClass(){
		System.out.println("teardown class");
	}
	
	@AfterSuite
	public static void teardownSuite(){
		System.out.println("teardown suite");
	}
}

that is yielding the following output:

init suite
init class
init test
inside test1
teardown test
init test
inside test2
teardown test
teardown class
PASSED: test1
PASSED: test2

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

teardown suite

===============================================
Default suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

You can find the code in this Github repository