Ok, so I have a class like this
public class Calculator {
@Test(dataProvider = "dp")
public void add(int a, int b) {
System.out.println("Invoked add: a, b" + a + "," + b);
}
@DataProvider(name = "dp")
public Object[][] createData(ITestContext ctx) {
return new Object[][] { new Object[] { 1, 2 }, new Object[] { 2, 3 } };
}
When, the test runs, it would run add method twice. I want to track each invocation of add uniquely based on its input. So say, add is invoked with 1,2 as input then that's a unique invocation. If it fails, I want to store this information to a database with an invocation id.
How do I achieve this using testng? All of the listeners (methodinvocationlistener etc), do not seem to provide context that uniquely identifies a method run. Yes, they do let you see the parameters, but I cannot track individual parameters. So, do I somehow inject my own unique parameter into the result object and track it from there?
UPDATE
I am adding improved code, to help understand the context better. This is my testng.xml
<suite name="Default Suite">
<test name="test">
<classes>
<class name="com.test.testng.Calculator">
<methods>
<include name="add">
<parameter name="data-id" value="1"/>
</include> <!-- add -->
<include name="add">
<parameter name="data-id" value="2"/>
</include> <!-- add -->
<include name="subtract">
<parameter name="data-id" value="3"/>
</include> <!-- subtract -->
</methods>
</class> <!-- com.test.testng.Calculator -->
</classes>
</test> <!-- test -->
</suite> <!-- Default Suite -->
I have two invocations of add and one invocation of subtract. Here's my data provider
public class Calculator {
@Test(dataProvider = "dp")
public void add(int first, int second) {
System.out.println("invoked add");
}
@Test(dataProvider = "dp")
public void subtract(int first, int second) {
System.out.println("invoked subtract");
}
@DataProvider(name = "dp")
public Object[][] createData(Method m, ITestContext ctx) {
Object[][] data = new Object[][] { new Object[] { 1, 2 }, new Object[] { 2, 3 }, new Object[] { 3, 4 } };
for (XmlClass test : ctx.getCurrentXmlTest().getXmlClasses()) {
for (XmlInclude method : test.getIncludedMethods()) {
if (method.getName().equals(m.getName()))
int key = Integer.parseInt(method.getAllParameters().get("data-id"));
return new Object[][] { data[key - 1] };
}
}
return null ;
}
}
I expected, add to run twice, once with 1,2 as input and another time with 2,3 as input. Similarly, subtract with 3,4 as input. But, what I saw was this -
[SuiteRunner] Created 1 TestRunners
[TestRunner] Running test test on 1 classes, included groups:[] excluded groups:[]
===== Test class
com.test.testng.Calculator
@Test Calculator.add(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]
@Test Calculator.subtract(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]
======
method.getAllParamas(){data-id=1}
[Invoker 665576141] Invoking com.test.testng.Calculator.add
invoked
[Invoker 665576141] Invoking com.test.testng.Calculator.subtract
subtract
===== Invoked methods
Calculator.add(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]1 2 966808741
Calculator.subtract(int, int)[pri:0, instance:com.test.testng.Calculator@39a054a5]1 2 966808741
=====
I need to provide data to each method based on the special parameter that I am going to send from testng xml. How do I achieve this?