Thursday, 5 July 2012

How to call the test plans dynamically

How to call the test plans dynamically using testng?

We can call the test plans dynamically using @Factory Annotation in testng.

Factories - Factories allow you to create tests dynamically
@Factory - Marks a method as a factory that returns objects that will be used by TestNG as Test classes. The method must return Object[].

Please find the below steps
  1. In your MainTestPlan have a method with @Factory annotation which determines the type of test plan to be called dynamically and return the Object array
  2. Have your Test Plans with your test methods
  3. Configure your testng.xml file using classes tag and define your main test plan class name
Please find the sample code below.
 
------------------------------------------------------------------------------------------------------
1.  TestPlan1.java

package com.test.sample;
import org.testng.annotations.Test;

public class TestPlan1{
   
    @Test
    public void testPlan1Method1()throws Exception {
        System.out.println("testPlan1Method1- invoked");
    }
   
    @Test
    public void testPlan1Method2()throws Exception {
        System.out.println("testPlan1Method2 - invoked");
    }
   

   @Test
    public void testPlan1Method3()throws Exception {
        System.out.println("testPlan1Method3- invoked");
    }
   
    @Test
    public void testPlan1Method4()throws Exception {
        System.out.println("testPlan1Method4 - invoked");
    }
 }


2.  TestPlan2.java


package com.test.sample;
import org.testng.annotations.Test;

public class TestPlan2{
   
  @Test
    public void testPlan2Method1()throws Exception {
        System.out.println("testPlan2Method1- invoked");
    }
   
    @Test
    public void testPlan2Method2()throws Exception {
        System.out.println("testPlan2Method2 - invoked");
    }

}



3. DynamicTestPlanTest.java 


package com.test.sample;

import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.Factory;

public class DynamicTestPlanTest {
    TestPlan1 obj1;
    TestPlan2 obj2;
   
    @Factory
    public Object[] setUp() throws Exception {
       List list=new ArrayList();
       
        int a=30,b=20,c;
       
        if(a>b){
            obj1=new TestPlan1();
            list.add(obj1);
        }else{
            obj2=new TestPlan2();
            list.add(obj2);
        }
       
        Object[] data = list.toArray(); 
        return data;
    }
   
}


4. testng.xml

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="DynamicTestPlanTestSuite" verbose="1" >
      
    <test name="DynamicTestPlanTest" preserve-order="true">
    <classes>
        <class name="com.test.sample.DynamicTestPlanTest"></class>
    </classes>
    </test>
</suite>


Output:

testPlan1Method1- invoked
testPlan1Method2- invoked
testPlan1Method3- invoked
testPlan1Method4- invoked








 

How to execute the testng test methods in order we specified?
We can execute the testng test methods in order we specified using Priority IMethodInterceptor

1. Declare a class(PriorityInterceptor) implementing the interface IMethodInterceptor
2. TestNG passes the list of methods it's about to run so you get a chance to reorder them.
3. We can declare three kinds of priorities:
    1. Priorities at the method level.
    2. A priority at the class level.
    3. No priority. When no priority is defined on a method, we want to look for a priority on the class first, and if none can be found, the priority will receive a default value of 0.
4. In your testplan(PriorityTestPlan) define the Priority as shown below


@Priority(1)
 @Test
 public void method1()  {
 System.out.println("method 1 invoked");
 }
 @Priority(-1)
 @Test
 public void method2()  {
 System.out.println("method 2 invoked");
 }

5. Next, we need to implement the @Priority annotation
6. Now we need to declare our interceptor in the testng.xml file using listner tags.

Please find below the sample code for calling the test methods in order we specified using Priority IMethodInterceptor

Sample Code Below:
--------------------------------------------------------------------------------------------------------

1. PriorityInterceptor.java

package com.test;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;

import com.test.Priority;

public class PriorityInterceptor implements IMethodInterceptor {

      public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() {
         
          private int getPriority(IMethodInstance mi) {
            int result = 0;
            Method method = mi.getMethod().getMethod();
            Priority a1 = method.getAnnotation(Priority.class);
            if (a1 != null) {
              result = a1.value();
            } else {
              Class cls = method.getDeclaringClass();
              Priority classPriority = (Priority) cls.getAnnotation(Priority.class);
              if (classPriority != null) {
                result = classPriority.value();
              }
            }
            return result;
          }

          public int compare(IMethodInstance m1, IMethodInstance m2) {
            return getPriority(m1) - getPriority(m2);
          }
         
        };
        IMethodInstance[] array = methods.toArray(new IMethodInstance[methods.size()]);
        Arrays.sort(array, comparator);

        return Arrays.asList(array);
      }

    }

 2. Priority.java
package com.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD, ElementType.TYPE})
public @interface Priority {
  int value() default 0;
}


3. PriorityTestPlan.java

package com.test;

import org.testng.annotations.Test;

public class PriorityTestPlan   {
  @Test
  public void method1() { System.out.println("M1 Default priority");}

  @Priority(1)
  @Test
  public void method2()  { System.out.println("M2 Priority 1");}
 
  @Priority(3)
  @Test
  public void method3()  { System.out.println("M3 Priority 3");}
 
  @Priority(-1)
  @Test
  public void method4()  { System.out.println("M4 Priority -1");}

  @Priority(2)
  @Test
  public void method5()  { System.out.println("M5 Priority 2");}

  @Priority(2)
  @Test
  public void method6()  { System.out.println("M6 Priority 2");}

}

4. testng.xml

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="PriorityTestSuite" verbose="1" >
    <listeners>
        <listener class-name="com.test.PriorityInterceptor" />
    </listeners>

   
    <test name="PriorityTestPlan" preserve-order="true">
    <classes>
        <class name="com.test.PriorityTestPlan"></class>
    </classes>
    </test>
</suite>


Output:

M4 Priority -1
M2 Priority 1
M5 Priority 2
M6 Priority 2
M3 Priority 3
M1 Default priority