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
Enable or disable a test
Add data provider at run time
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.
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 a java test class, say, TestTransformer.java(that implements IAnnotationTransformer) in /work/testng/src.
Create a java test class, say, TestTransformer.java(that implements IAnnotationTransformer) in /work/testng/src.
Override method transform().
Override method transform().
Add an Annotation @Test to methods test1() and test2() and group them.
Add an Annotation @Test to methods test1() and test2() and group them.
Add logic to skip tests with group name betaTest.
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);
  		}
  	}
  }
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
  ===============================================


    38 Lectures 
     4.5 hours 

 Lets Kode It

    15 Lectures 
     1.5 hours 

 Quaatso Learning

    28 Lectures 
     3 hours 

 Dezlearn Education
 Print
 Add Notes
 Bookmark this page