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:-
test name=”TmpTest”
<classes>
<class name=”demo.rmi.print.client.NewTest”>
<methods>
<include name=”f” />
<include name=”f1″ />
<include name=”f” />
</methods>
</class>
</classes>
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.
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<String> testMethodList;
@BeforeTest
public void beforeTestMethod(ITestContext context,XmlTest currentTest){
testMethodList = new ArrayList<String>();
String xml = context.getCurrentXmlTest().toXml(“5″);
Pattern pattern = Pattern.compile(“(\\<include name=\”)(.+)(\”/>)”);
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;
}
TestNG.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<suite name=”TmpSuite” >
<listeners>
<listener class-name=”demo.rmi.print.client.listener” />
</listeners>
<test name=”TmpTest” >
<classes>
<class name=”demo.rmi.print.client.NewTest”>
<methods>
<include name=”f” />
<include name=”f1″ />
<include name=”f” />
</methods>
</class>
</classes>
</test>
<test name=”Test2″ >
<classes>
<class name=”demo.rmi.print.client.NewTest”>
<methods>
<include name=”f1″ />
<include name=”f1″ />
<include name=”f” />
</methods>
</class>
</classes>
</test>
</suite>
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.
<test>
<parameter name=”mlist” value=”f,f1,f1″
</test>
<test>
<parameter name=”mlist” value=”f,f,f1″
</test>
Get the parameters from MethodInterceptor and proceed.
No comments:
Post a Comment