问题
I have the following Reporting code:
public class Reporting {
private ExtentHtmlReporter extentHtmlReporter;
private static ThreadLocal<ExtentReports> extentReports = new ThreadLocal<>();
private static ThreadLocal<ExtentTest> extentTest = new ThreadLocal<>();
public synchronized ExtentTest createInstanceReport(String testCaseName) {
System.out.println(extentReports.get());
new File(Constants.userDir + "/Reports/").mkdirs();
// To generate report with name
extentHtmlReporter = new ExtentHtmlReporter(
Constants.userDir + "/Reports/" +
"ExecutionReport_" + new SimpleDateFormat(
Constants.date).format(new Date()) + ".html");
// Setting Document Title
extentHtmlReporter.config().setDocumentTitle("Demo");
// Setting Report Name
extentHtmlReporter.config().setReportName("Demo Automation");
// Setting Theme
extentHtmlReporter.config().setTheme(Theme.STANDARD);
// Setting Chart location
extentHtmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
// Setting Chart visibility
extentHtmlReporter.config().setChartVisibilityOnOpen(false);
// Setting Time stamp
extentHtmlReporter.config().setTimeStampFormat("yyyy-MM-dd HH:mm:ss");
// Setting append exist as true
extentHtmlReporter.setAppendExisting(true);
ExtentReports extentReports = new ExtentReports();
extentReports.attachReporter(extentHtmlReporter);
// Setting system info
extentReports.setSystemInfo("Name",
BaseTest.prop.getProperty(Constants.testerName));
extentReports.setSystemInfo("Environment",
BaseTest.prop.getProperty(Constants.environment));
extentReports.setSystemInfo("Browser",
BaseTest.prop.getProperty(Constants.browser));
Reporting.extentReports.set(extentReports); // Instead of using here extentReport thread like this, Can anyone suggest to use it directly
// Add test case name in report
ExtentTest extentTest = Reporting.extentTest.get();
extentTest = Reporting.extentReports.get().createTest(testCaseName);
Reporting.extentTest.set(extentTest);
// Assigning categories
extentTest.assignCategory(MultiFunction.getProp()
.getProperty(Constants.browser));
System.out.println(Reporting.extentReports.get());
System.out.println(Reporting.extentTest.get());
return extentTest;
}
public synchronized ExtentTest getExtentTest() {
return extentTest.get();
}
public synchronized ExtentReports getInstanceReport() {
return extentReports.get();
}
public synchronized void remove() {
extentReports.remove();
extentTest.remove();
}
}
I was trying parallel testing using TestNG (and will have to use Selenium grid and sauce in future). I execute 2 test cases then only one test case result is added in the report.
I have isolated the extentTest
, extentReporter
and WebDriver instances using threadPool.
Tried below with extentHtmlReporter
instance:
1) Tried to make it static(no luck)
2) Tried to make it local (the same behaviour, getting only 1 test case result)
3) Tried as a non-static global variable ( no luck)
Could you suggest how to solve the above issue?
Please note: Only one report is generated. But when I tried to run parallel test cases in debug mode reports are generated for both the test case. I think because one test case gets over its killing some instance (when running in non-debug mode)
Also, I want to redesign the following place in my code:
For extentRpeort
, I am using:
Reporting.extentReports.set(extentReports);
To add extentReport
instance to my extentReport
Thread.
Instead of adding like this I want to use it directly so as to reduce line of code.
回答1:
If I understand correctly you have to generate Report from all executed TestNG cases.
However, from code which you shared, it is very visible that you will have some trouble with it. You are making a few critical mistakes and result are obvious:
For generating reports with TestNG I will suggest grabbing information about test execution from TestNG listener. Something like:
public final class TestNGListener extends TestListenerAdapter implements IInvokedMethodListener, ISuiteListener { @Override public void onStart(ITestContext context) { Logger.info(buildMessage(Logger.PREFIX_TEST_STARTED, context.getName())); } @Override public void onFinish(ITestContext context) { Logger.info(buildMessage(Logger.PREFIX_TEST_FINISHED, context.getName())); } @Override public void onTestStart(ITestResult result) { Logger.info(buildMessage(Logger.PREFIX_METHOD_STARTED, getMethodName(result))); } @Override public void onTestSuccess(ITestResult result) { Logger.info(buildMessage(Logger.PREFIX_METHOD_SUCCESS, getMethodName(result))); processTestResult(result); } @Override public void onTestFailure(ITestResult result) { Logger.info(buildMessage(Logger.PREFIX_METHOD_FAILED, getMethodName(result))); }
You can't do everything in one method! You broke Single Responsibility Principle. Your
createInstanceReport()
is doing all jobs (setting report details, set system info, attach an executed test case to report) at one place. You have to redesign this logic to some logical separate operations. After redesigning your problem with the next line:
Reporting.extentReports.set(extentReports)
Could successfully disappear.
- You have to consider a case, why you need to use exactly
Extent, Reports Version 3
. TestNG has test reports from the box. They are poor but they are presented out of the box. If you want just to improve it a little bit you could use ReportNG over TestNG.
It is quite easy to configure: Configuring ReportNG with TestNG for HTML Reports.
It isn't maintained, but it makes TestNG reports really eye candy and understandable.
Anyway, my suggestion is to use TestNGListener
for getting info about test cases execution. And read more about good programming practice.
回答2:
Work with TestNG/jUnit (or other runner framework that you are using) listener, here is a good example how to do it. Do not put everything in a single class.
https://www.swtestacademy.com/extent-reports-version-3-reporting-testng/
回答3:
The issue was with the flushing of extent report instance. I was using ThreadLocal for storing extent report instance and was flushing the wrong instance.
回答4:
I used Extent Reports for several time but then found nice SDK from TestProject automation platform. It's free so i'd recommend it to all those who tired from all this setting with reports. Here's how it looks like
reporter.step("Outbound date selected", selectedMonth.equals(months[monthFromIndex]), TakeScreenshotConditionType.Always);
and screenshot of the step report
Results
来源:https://stackoverflow.com/questions/52811017/extent-report-issue-parallel-testing