Reputation: 29669
I tried following instructions on this thread but they fail to work for me. Basically I need to figure out how to set the TestNG test name, as seen on the HTML report, dynamically from the DataProvider input.
I created a GitHub project that re-creates the problem I am experiencing and I am hoping someone can help me solve it? I created a CustomReport class that reveals the "test name" on the HTML report but the test name is not yet shown correctly.
To solve this, all I need is to modify the CustomReport class to somehow read the name values from the ITestContext object, after the tests are finished, and report them on the report properly.
So far I am able to show in my GitHub test project that I can print out the correct individual names to the console but I just need to figure out how to print them on the report.
Upvotes: 1
Views: 3692
Reputation: 4045
djangofan, not sure if you found a way or not, but i figured out a way to do it from using your repro, albeit a bit hacky, part of which i snagged from this post.
Here, create attribute names, but do not increment the names. That causes the attribute list to grow, and then you lose context of which attribute belongs to which test. For all intents and purposes, we only want to id a single test name:
@Test( dataProvider = "dp" )
public void testSample1( int num, String name, String desc, ITestContext ctx ) {
//ctx.setAttribute( "testName" + num, name );
//ctx.setAttribute( "testDesc" + num, desc );
ctx.setAttribute("testName", name);
ctx.setAttribute("testDesc", desc);
assertTrue( true );
}
Now create your custom listener, here we will set the method name equal to the attribute name, and will be reflected in the testng-results.xml file. Note, we are hard-coding "testName" parameter name.
public class CustomListener extends TestListenerAdapter {
@Override
public void onTestSuccess(ITestResult tr) {
setTestNameInXml(tr);
super.onTestSuccess(tr);
}
...
private void setTestNameInXml(ITestResult tr) {
try
{
ITestContext ctx = tr.getTestContext();
Set<String> attribs = ctx.getAttributeNames();
for ( String x : attribs ) {
if (x.contains("testName")) {
Field method = TestResult.class.getDeclaredField("m_method");
method.setAccessible(true);
method.set(tr, tr.getMethod().clone());
Field methodName = BaseTestMethod.class.getDeclaredField("m_methodName");
methodName.setAccessible(true);
methodName.set(tr.getMethod(), ctx.getAttribute( x ));
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
This will automatically replace the actual method name in the "Method Name" column with the test case name set in the attributes.
It is not ideal to update testng-results.xml file, but it was easiest solution based on your code, plus i think it will work for me!
Upvotes: 2