- TestNG - Home
- TestNG - Overview
- TestNG - Environment
- TestNG - Writing Tests
- TestNG - Basic Annotations
- TestNG - Execution Procedure
- TestNG - Executing Tests
- TestNG - Suite Test
- TestNG - Ignore a Test
- TestNG - Group Test
- TestNG - Exception Test
- TestNG - Dependency Test
- TestNG - Parameterized Test
- TestNG - Run JUnit Tests
- TestNG - Test Results
- TestNG - Annotation Transformers
- TestNG - Asserts
- TestNG - Parallel Execution
- TestNG - Plug with ANT
- TestNG - Plug with Eclipse
- TestNG - TestNG - vs JUnit
TestNG - Basic Annotations - Transformers
In some scenarios you might want to execute TestNG tests based on some condition or criteria that is evaluated dynamically while test execution is in progress.Such as :
Enable or disable a test
Add data provider at run time
In order to achieve this, you need to use an Annotation Transformer. An Annotation Transformer is a class that implements the following interface:
public interface IAnnotationTransformer {
/**
* This method will be invoked by TestNG to give you a chance
* to modify a TestNG annotation read from your test classes.
* You can change the values you need by calling any of the
* setters on the ITest interface.
*
* Note that only one of the three parameters testClass,
* testConstructor and testMethod will be non-null.
*
* @param annotation The annotation that was read from your
* test class.
* @param testClass If the annotation was found on a class, this
* parameter represents this class (null otherwise).
* @param testConstructor If the annotation was found on a constructor,
* this parameter represents this constructor (null otherwise).
* @param testMethod If the annotation was found on a method,
* this parameter represents this method (null otherwise).
*/
public void transform(ITest annotation, Class testClass,
Constructor testConstructor, Method testMethod);
}
You can specify this class either on the command line or with ant as shown below:
java org.testng.TestNG -listener TestTransformer testng.xml
or programmatically as shown below:
TestNG test = new TestNG(); test.setAnnotationTransformer(new TestTransformer()); // ...
This interface IAnnotationTransformer modifies the default TestNG tests behavior at run time. Using this listener, we can modify values of all attributes defined in @Test annotation by calling their setters.
Create a Class
Let's see the usage of annotation transformer in below example. Let us skip tests that are tagged to a specified group without changing TestNG suite every time. Create a java class to be tested, say, ListenerTest.java in /work/testng/src.
import org.testng.annotations.Test;
public class ListenerTest {
@Test(groups={"betaTest","aplhaTest"})
public void test1() {
System.out.println("I am test1");
}
@Test(groups={"aplhaTest"})
public void test2() {
System.out.println("I am test2");
}
}
Create Tansformer class Case Class
Create a java test class, say, TestTransformer.java(that implements IAnnotationTransformer) in /work/testng/src.
Override method transform().
Add an Annotation @Test to methods test1() and test2() and group them.
Add logic to skip tests with group name betaTest.
Following are the TestTransformer.java contents.
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
public class TestTransformer implements IAnnotationTransformer{
@Override
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) {
List groupNames = Arrays.asList(annotation.getGroups());
System.out.println(groupNames.toString());
//Value 'betaTest' can be read from many places like properties file, run time parameter etc...
//For Simplicity, group is hardcoded in this program
String groupNameToSkip = "betaTest";
if(groupNames.contains(groupNameToSkip)){
System.out.println("found group name");
annotation.setEnabled(false);
}
}
}
Create testng.xml
Next, let's create testng.xml file in /work/testng/src, to execute test case(s).
<suite name="Suite" parallel="classes" thread-count="2">
<listeners>
<listener class-name="TestTransformer"></listener>
</listeners>
<test name="Test">
<classes>
<class name="ListenerTest"/>
</classes>
</test>
</suite>
Compile the test case using javac.
/work/testng/src$ javac TestTransformer.java ListenerTest.java
Now, run the testng.xml, which will run the test case defined in <test> tag. As you can see the tests grouped under name betaTest are skipped.
/work/testng/src$ java org.testng.TestNG testng.xml
Verify the output.
[aplhaTest] [betaTest, aplhaTest] found group name I am test2 =============================================== Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================