0
votes

I am using testng 6.9.10, extentreports 3.1.5. Using maven surefire plugin and using forkcount and reuse forks , the tests running in parallel. (i.e two instances of chrome browser opening with two tests classes running in parallel as I set forkcount -> 2 and reuseforks-> true)

mvn test -Dgroups=group1 

( there are two test classes belong to group1). The problem is extent report only shows the result of the last run.

I've included only the listener class in pom.xml ( not anywhere else, Not in the @beforeclass or @afterclass as part of BaseTest class)

  <property>
    <name>listener</name>
    <value>util.listener.TestExtentListener</value>
  </property>


   <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <forkCount>2</forkCount>
    <reuseForks>true</reuseForks>

Any solution please?

public class ExtentManager {

private static ExtentReports extent;
private static String reportFileName = "Test-Automaton-Report"+".html";
private static String fileSeperator = System.getProperty("file.separator");
private static String reportFilepath = System.getProperty("user.dir") +fileSeperator+ "TestReport";
private static String reportFileLocation =  reportFilepath +fileSeperator+ reportFileName;


public static ExtentReports getInstance() {
    if (extent == null)
        createInstance();
    return extent;
}

//Create an extent report instance
public static ExtentReports createInstance() {
    String fileName = getReportPath(reportFilepath);

    ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(fileName);
    htmlReporter.config().setTestViewChartLocation(ChartLocation.BOTTOM);
    htmlReporter.config().setChartVisibilityOnOpen(true);
    htmlReporter.config().setTheme(Theme.STANDARD);
    htmlReporter.config().setDocumentTitle(reportFileName);
    htmlReporter.config().setEncoding("utf-8");
    htmlReporter.config().setReportName(reportFileName);
    htmlReporter.config().setTimeStampFormat("EEEE, MMMM dd, yyyy, hh:mm a '('zzz')'");

    extent = new ExtentReports();

    extent.attachReporter(htmlReporter);
    //Set environment details
    extent.setSystemInfo("OS", "Mac");
    extent.setSystemInfo("AUT", "QA");

    return extent;
 }

//Create the report path
private static String getReportPath (String path) {
    File testDirectory = new File(path);
    if (!testDirectory.exists()) {
        if (testDirectory.mkdir()) {
            System.out.println("Directory: " + path + " is created!" );
            return reportFileLocation;
        } else {
            System.out.println("Failed to create directory: " + path);
            return System.getProperty("user.dir");
        }
    } else {
        System.out.println("Directory already exists: " + path);
    }
    return reportFileLocation;
}

}

public class ExtentTestManager {
static Map<Integer, ExtentTest> extentTestMap = new HashMap<Integer, ExtentTest>();
static ExtentReports extent = ExtentManager.getInstance();

public static synchronized ExtentTest getTest() {
    return (ExtentTest) extentTestMap.get((int) (long) (Thread.currentThread().getId()));
}

public static synchronized void endTest() {
    extent.flush();
}

public static synchronized ExtentTest startTest(String testName) {
    ExtentTest test = extent.createTest(testName);
    extentTestMap.put((int) (long) (Thread.currentThread().getId()), test);
    return test;
}
}

public class TestExtentListener implements ITestListener {

ExtentTest test;
private static ThreadLocal<ExtentTest> extentTestThreadLocal = new ThreadLocal<ExtentTest>();


public void onStart(ITestContext context) {
    System.out.println("*** Test Suite " + context.getName() + " started ***");
}

public void onFinish(ITestContext context) {
    System.out.println(("*** Test Suite " + context.getName() + " ending ***"));
    ExtentTestManager.endTest();
    ExtentManager.getInstance().flush();
}

public void onTestStart(ITestResult result) {
    System.out.println(("*** Running test method " + result.getMethod().getMethodName() + "..."));
    test = ExtentTestManager.startTest(result.getMethod().getMethodName());
    extentTestThreadLocal.set(test);
}

public void onTestSuccess(ITestResult result) {
    System.out.println("*** Executed " + result.getMethod().getMethodName() + " test successfully...");
    extentTestThreadLocal.get().log(Status.PASS, "Test passed");
}

public void onTestFailure(ITestResult result) {
    System.out.println("*** Test execution " + result.getMethod().getMethodName() + " failed...");
    extentTestThreadLocal.get().log(Status.FAIL, "Test Failed");
}

public void onTestSkipped(ITestResult result) {
    System.out.println("*** Test " + result.getMethod().getMethodName() + " skipped...");
    extentTestThreadLocal.get().log(Status.SKIP, "Test Skipped");
}

public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
    System.out.println("*** Test failed but within percentage % " + result.getMethod().getMethodName());
}

}

2

2 Answers

1
votes

you might not be using thread local class in java to make extent report thread safe. Otherwise objects will get overridden and extent report only shows the active tests results.

You can do something like this:

ExtentReports extent = ExtentReportGenerator.ExtentReport();
    ExtentTest test;;

    private static ThreadLocal<ExtentTest> extent_test = new ThreadLocal<ExtentTest>();

For more details, you can refer to this blog.

https://www.automationinja.com/post/thread-safe-extent-report-in-selenium

0
votes
    If you use xml file to your testclasses all report will appear in extent report 
    
    This is my XML 
    
        <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="TC_WorldAirFares Automation Test Suite">
    
        <listeners>
            <listener class-name="ExtentReports.ExtentReporterNG" />
        </listeners>
  <suite name="Suite" parallel="instances" thread-count="2">
    <test name="TC Automation Test Suite">
            <classes>
    
                <class name="Footerlinks" />
                <class name="HeaderLinks" />
                <class name="BookYourFlightsNow" />
              
            </classes>
        </test>
    
       
    </suite>
    
    
    keep class for extentreports
    
    here extent report class (XML file listen your extentreport class and generate reports for you test classes
    
        package ExtentReports;
    
    import com.relevantcodes.extentreports.ExtentReports;
    import com.relevantcodes.extentreports.ExtentTest;
    import com.relevantcodes.extentreports.LogStatus;
    import org.testng.*;
    import org.testng.xml.XmlSuite;
    
    import java.io.File;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    
    public class ExtentReporterNG implements IReporter {
        private ExtentReports extent;
    
        public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
                                   String outputDirectory) {
            extent = new ExtentReports(outputDirectory + File.separator
                    + "Extent.html", true);
    
            for (ISuite suite : suites) {
                Map<String, ISuiteResult> result = suite.getResults();
    
                for (ISuiteResult r : result.values()) {
                    ITestContext context = r.getTestContext();
    
                    buildTestNodes(context.getPassedTests(), LogStatus.PASS);
                    buildTestNodes(context.getFailedTests(), LogStatus.FAIL);
                    buildTestNodes(context.getSkippedTests(), LogStatus.SKIP);
                }
            }
    
            extent.flush();
            extent.close();
        }
    
        private void buildTestNodes(IResultMap tests, LogStatus status) {
            ExtentTest test;
    
            if (tests.size() > 0) {
                for (ITestResult result : tests.getAllResults()) {
                    test = extent.startTest(result.getMethod().getMethodName());
    
                    test.setStartedTime(getTime(result.getStartMillis()));
                    test.setEndedTime(getTime(result.getEndMillis()));
    
                    for (String group : result.getMethod().getGroups())
                        test.assignCategory(group);
    
                    if (result.getThrowable() != null) {
                        test.log(status, result.getThrowable());
                    } else {
                        test.log(status, "Test " + status.toString().toLowerCase()
                                + "ed");
                    }
    
                    extent.endTest(test);
                }
            }
        }
    
        private Date getTime(long millis) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(millis);
            return calendar.getTime();
        }
    }