Thursday, July 26, 2012

TestNG Executing Duplicate Methods

Pre-Requisite :-
 - Basic Idea on TestNG
 - Idea of executing test methods through testNG.xmls 
- Idea on MethodInterceptor,TestNG context

 Again... i got an opportunity to execute a testNG method more than once within a testNG.xml test tag. With current implementation of TestNG , we can not execute same test method twice.. For ex:- With current TestNG version, the method name "f" will be executed only once .. as TestNG uses Set to execute test methods , duplicate method name will be removed. 

 Problem Statement :- To execute TestNG method more than once within a test tag. So that we can execute the testNG tests similar to keyword driven approach

 Solution :- Step 1- Get the TestNG.xml (current test XML notation as String)
 Step 2- Get the list of method names to be executed which is [f,f1,f] in the BeforeTest method.
 Step 3- Convert this List as String and store it as a parameter of the current test being executed using context object. 
 Step 4- Write a MethodInterceptor Listener and get the parameter string having list of test methods. 
 Step 5- Get the current list of test methods through MethodInterceptor. 
 Step 6- Parse the list of methodnames with the methodnames retrieved from the current list of test methods.        Step 7- Insert the method instance to the new list including duplicates 
 Step 8- Return the list to TestNG.

 Implementation :- STEP 1 ,2,3

 public class NewTest { 
 List testMethodList;
 @BeforeTest
 public void beforeTestMethod(ITestContext context,XmlTest currentTest)
{ 
 testMethodList = new ArrayList();
 String xml = context.getCurrentXmlTest().toXml("5"); 
 Pattern pattern = Pattern.compile("(\\)"); 
 Matcher matcher = pattern.matcher(xml); 

 while(matcher.find()){ 
     testMethodList.add(matcher.group(2)); 
 } 
 context.getCurrentXmlTest().addParameter("methodList", Arrays.toString(testMethodList.toArray()));

 STEP 4,5,6,7,8


public class listener  extends NewTest implements IMethodInterceptor  {

List<String> strMethodList;
public IMethodInstance getInstance(String name,List<IMethodInstance> lm){
for(int i=0;i<lm.size();i++){
if(lm.get(i).getMethod().getMethodName().trim().equals(name.trim())){
return lm.get(i);
}
}
return null;
}
@Override
public List<IMethodInstance> intercept(List<IMethodInstance> mlist,
ITestContext context) {
    String mList = context.getCurrentXmlTest().getParameter("methodList");
    mList = mList.replaceAll("\\[", "");
    mList = mList.replaceAll("\\]", "");
    String[] mL = mList.split(",");
    strMethodList  = Arrays.asList(mL);
List<IMethodInstance> result = new ArrayList<IMethodInstance>();
for(int i=0;i<strMethodList.size();i++){
result.add(getInstance(strMethodList.get(i),mlist));
}
return result;
}
Add this listener to testNg.xml.



Note :- If you want to do the parallel execution of the tests make sure , you are defining a parameter specific to each test tag (having same name). and mention the included methods seperated by comma. Get the parameters from MethodInterceptor and proceed.

No comments:

Post a Comment