Extent Report Issue Parallel testing

折月煮酒 提交于 2019-12-11 02:59:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!