artdanil的回答没有完全解决我的问题,在emailable报告中测试名称没有更新。
@jersey-city-ninja发布的答案会更新Emailable报告中的名称,但它会为所有Dataprovider值重复相同的最后更新的测试名称,因为pilotg2发布的内容对于使用Dataprovider的测试是正确的,即getTestName方法保持返回方法的最后设置名称,并且Dataprovider的所有测试名称都相同。
所以这里是答案,它是@pilotg2和@jersey-city-ninja发布的答案的组合,并带有额外的步骤来克服重复的方法名称。
注意:这将更新Emailable报告、XML报告、HTML报告和Junit报告中的测试名称。我没有看到它更新Eclipse-TestNg执行视图-如果我找到了什么,我会更新。
import org.testng.Assert;
import org.testng.ITest;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class NewDataProviderTest implements ITest {
private ThreadLocal<String> testName = new ThreadLocal<>();
private int emailNameIndex = 0;
private int htmlNameIndex = 0;
private int xmlNameIndex = 0;
private ArrayList<String> allTests = new ArrayList<String>();
private ArrayList<String> passedTests = new ArrayList<String>();
private ArrayList<String> failedTests = new ArrayList<String>();
@BeforeClass(alwaysRun = true)
public void initialize() {
this.testName.set("");
}
@BeforeMethod(alwaysRun = true)
public void setCustomTestcaseName(Method method, Object[] testData) {
this.testName.set(method.getName());
if (testData != null && testData.length > 0) {
System.out.println("\n\nParameters "+testData[0]+" are passed to the test - "+method.getName());
if (testData[0] instanceof String) {
System.out.println("I'm setting custom name to the test as "+method.getName() + "_" + testData[0]);
this.testName.set(method.getName() + "_" + testData[0]);
}
}
allTests.add(testName.get());
}
@AfterMethod (alwaysRun = true)
public void setTheTestcaseNameInResult(ITestResult result, Method method) {
try {
if(result.getStatus() == ITestResult.SUCCESS) {
System.out.println("Adding "+ result.getTestName() + " to passed tests collection");
passedTests.add(result.getTestName());
}
if(result.getStatus() == ITestResult.FAILURE) {
System.out.println("Adding " + result.getTestName() + " to FAILURE tests collection");
failedTests.add(result.getTestName());
}
} catch (Exception e) {
e.printStackTrace();
}
if(iTestResult.getParameters().length > 0) {
if (iTestResult.getParameters()[0] instanceof String) {
System.out.println("Updating the name as Parameters are passed to the test-"+method.getName());
try {
Field resultMethod = TestResult.class.getDeclaredField("m_method");
resultMethod.setAccessible(true);
resultMethod.set(iTestResult, iTestResult.getMethod().clone());
Field methodName = org.testng.internal.BaseTestMethod.class.getDeclaredField("m_methodName");
methodName.setAccessible(true);
methodName.set(iTestResult.getMethod(), this.getTestName());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("New Name is - " + iTestResult.getMethod().getMethodName());
}
}
}
@Override
public String getTestName() {
String name = testName.get();
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (isCalledFromMethod(stackTrace, "XMLSuiteResultWriter")) {
if (allTestNames.size() > 0) {
if (xmlNameIndex < allTestNames.size()) {
name = allTestNames.get(xmlNameIndex);
} else {
name = allTestNames.get(0);
}
} else {
name = "undefined";
}
xmlNameIndex++;
if (xmlNameIndex >= allTestNames.size()) {
xmlNameIndex = 0;
}
} else if (isCalledFromMethod(stackTrace, "EmailableReporter")) {
if (allTestNames.size() > 0) {
if (emailNameIndex < allTestNames.size()) {
name = allTestNames.get(emailNameIndex);
} else {
name = allTestNames.get(0);
}
} else {
name = "undefined";
}
emailNameIndex++;
if (emailNameIndex >= allTestNames.size()) {
emailNameIndex = 0;
}
System.out.println("Got called from EmailableReporter returning name -"+name);
}
if (isCalledFromMethod(stackTrace, "TestHTMLReporter")) {
if (allTestNames.size() <= 0) {
name = "undefined";
} else {
if (htmlNameIndex < failedTestNames.size()) {
name = failedTestNames.get(htmlNameIndex);
} else {
int htmlPassedIndex = htmlNameIndex - failedTestNames.size();
if (htmlPassedIndex < passedTestNames.size()) {
name = passedTestNames.get(htmlPassedIndex);
} else {
name = "undefined";
}
}
}
htmlNameIndex++;
if (htmlNameIndex >= allTestNames.size()) {
htmlNameIndex = 0;
}
System.out.println("Got called from TestHTMLReporter returning name - "+name);
}
System.out.println("Returning testname as-"+name);
return name;
}
private boolean isCalledFromMethod(StackTraceElement[] stackTrace, String checkForMethod) {
boolean calledFrom = false;
for (StackTraceElement element : stackTrace) {
String stack = element.toString();
if (stack.contains(checkForMethod))
calledFrom = true;
}
return calledFrom;
}
@Test(groups= {"L1", "L2", "L3"}, dataProvider = "dp1")
public void dataProviderTest(String username) {
System.out.println("\n\nI'm in dataProviderTest with data-"+username);
if(username.contains("L2")) {
Assert.fail();
}
}
@Test(dependsOnMethods = "dataProviderTest", groups= {"L1", "L2", "L3"}, dataProvider = "dp1")
public void dataProviderDependentTest(String username) {
System.out.println("\n\nI'm in dataProvider DEPENDENT Test with data-"+username);
}
@Test(groups= {"L1", "L2", "L3"}, dataProvider = "dp2")
public void dataListProviderTest(List<String[]> list) {
Object[] arr = list.get(0);
List<Object> arrList = Arrays.asList(arr);
Iterator<Object> iterator = arrList.iterator();
while (iterator.hasNext()) {
String[] data = (String[]) iterator.next();
System.out.println("In list test - "+data[0]);
}
}
@DataProvider(name="dp1")
public Object[][] getDataForTest(ITestContext iTestContext){
Object[][] L1 = new Object[][] {
{"L1"}, {"L2"}, {"L3"}
};
return L1;
}
@DataProvider(name="dp2")
public Object[][] getDataListForTest(ITestContext iTestContext){
List<Object[][]> list = new ArrayList<Object[][]>();
Object[][] L1 = new Object[][] {
new String [] {"L1", "l1"},
new String [] {"L1", "l1"}
};
list.add(L1);
return new Object[][] { { list } };
}
}