Extent Reports Version 3 Reporting with TestNG Listener

Hi all, in this article, I will describe how to integrate Extent Reports Version 3 reporting tool with TestNG Listener. Before I explained how to integrate extent reports version 2 and in this article, we will learn how to generate a test report with extent report version 3. Let’s start.

First, we need to add extent report maven dependency in out pom.xml as shown below.

 <!--Test reporting library - extent 3.X-->
<dependency>
     <groupId>com.aventstack</groupId>
     <artifactId>extentreports</artifactId>
     <version>3.1.5</version>
</dependency>

Second, we need to add ExtentManager class to our project. In this class, we create an ExtentReports instance, select the extent report file location based on a platform, and create the report path if it does not exist.

//**********************************************************************************************************
//Author: Onur Baskirt
//Description: ExtentReports related operations are done by this class. I added extra functionality such as
//"getCurrentPlatform". In this way, framework can create a report folder and file based on OS.
//Reference: http://extentreports.com/docs/versions/3/java/
//**********************************************************************************************************
public class ExtentManager {
    private static ExtentReports extent;
    private static Platform platform;
    private static String reportFileName = "ExtentReports-Version3-Test-Automaton-Report.html";
    private static String macPath = System.getProperty("user.dir")+ "/TestReport";
    private static String windowsPath = System.getProperty("user.dir")+ "\\TestReport";
    private static String macReportFileLoc = macPath + "/" + reportFileName;
    private static String winReportFileLoc = windowsPath + "\\" + reportFileName;

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

    //Create an extent report instance
    public static ExtentReports createInstance() {
        platform = getCurrentPlatform();
        String fileName = getReportFileLocation(platform);
        ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(fileName);
        htmlReporter.config().setTestViewChartLocation(ChartLocation.BOTTOM);
        htmlReporter.config().setChartVisibilityOnOpen(true);
        htmlReporter.config().setTheme(Theme.STANDARD);
        htmlReporter.config().setDocumentTitle(fileName);
        htmlReporter.config().setEncoding("utf-8");
        htmlReporter.config().setReportName(fileName);

        extent = new ExtentReports();
        extent.attachReporter(htmlReporter);

        return extent;
    }

    //Select the extent report file location based on platform
    private static String getReportFileLocation (Platform platform) {
        String reportFileLocation = null;
        switch (platform) {
            case MAC:
                reportFileLocation = macReportFileLoc;
                createReportPath(macPath);
                System.out.println("ExtentReport Path for MAC: " + macPath + "\n");
                break;
            case WINDOWS:
                reportFileLocation = winReportFileLoc;
                createReportPath(windowsPath);
                System.out.println("ExtentReport Path for WINDOWS: " + windowsPath + "\n");
                break;
            default:
                System.out.println("ExtentReport path has not been set! There is a problem!\n");
                break;
        }
        return reportFileLocation;
    }

    //Create the report path if it does not exist
    private static void createReportPath (String path) {
        File testDirectory = new File(path);
        if (!testDirectory.exists()) {
            if (testDirectory.mkdir()) {
                System.out.println("Directory: " + path + " is created!" );
            } else {
                System.out.println("Failed to create directory: " + path);
            }
        } else {
            System.out.println("Directory already exists: " + path);
        }
    }

    //Get current platform
    private static Platform getCurrentPlatform () {
        if (platform == null) {
            String operSys = System.getProperty("os.name").toLowerCase();
            if (operSys.contains("win")) {
                platform = Platform.WINDOWS;
            } else if (operSys.contains("nix") || operSys.contains("nux")
                    || operSys.contains("aix")) {
                platform = Platform.LINUX;
            } else if (operSys.contains("mac")) {
                platform = Platform.MAC;
            }
        }
        return platform;
    }
}

Then, we need to modify our TestNG listener class as shown below.

//**********************************************************************************************************
//Author: Onur Baskirt
//Description: This is the main listener class.
//**********************************************************************************************************
public class TestListener extends BaseTest implements ITestListener {

    //Extent Report Declarations
    private static ExtentReports extent = ExtentManager.createInstance();
    private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();

    @Override
    public synchronized void onStart(ITestContext context) {
        System.out.println("Extent Reports Version 3 Test Suite started!");
    }

    @Override
    public synchronized void onFinish(ITestContext context) {
        System.out.println(("Extent Reports Version 3  Test Suite is ending!"));
        extent.flush();
    }

    @Override
    public synchronized void onTestStart(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " started!"));
        ExtentTest extentTest = extent.createTest(result.getMethod().getMethodName(),result.getMethod().getDescription());
        test.set(extentTest);
    }

    @Override
    public synchronized void onTestSuccess(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " passed!"));
        test.get().pass("Test passed");
    }

    @Override
    public synchronized void onTestFailure(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " failed!"));
        test.get().fail(result.getThrowable());
    }

    @Override
    public synchronized void onTestSkipped(ITestResult result) {
        System.out.println((result.getMethod().getMethodName() + " skipped!"));
        test.get().skip(result.getThrowable());
    }

    @Override
    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        System.out.println(("onTestFailedButWithinSuccessPercentage for " + result.getMethod().getMethodName()));
    }
}

After that, you can run your tests and see the test results in TestReport folder as shown below.

Here is the sample project link: https://github.com/swtestacademy/extent-reports-version-3-example 

[fusion_widget_area name=”avada-custom-sidebar-seleniumwidget” title_size=”” title_color=”” background_color=”” padding_top=”” padding_right=”” padding_bottom=”” padding_left=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” class=”” id=””][/fusion_widget_area]

Thanks.
Onur Baskirt

18 thoughts on “Extent Reports Version 3 Reporting with TestNG Listener”

  1. Dear Onur Baskirt,

    That is a good article, it really helps us to understand how to apply extent report to our testing framework. The extent report looks beautiful and give us enough information on during test.

    As an Extent report, it just displays a one step for a test method with @Test annotation. What should i do to displays many steps result under extent report?
    I try to googled a solution but not.

    Thanks for your help,
    TN

    Reply
  2. Thanks Onur Baskirt,

    So, in this case, we bring the test steps to the report. Do we have the way to to marked the test steps failed, passed or skipped?

    Or we just mark the test case passed or failed.

    Thanks,

    Reply
  3. Dear Onur Baskirt,

    I have to tried the command which you gave me but the log does not include to the report. My testing classes are placed in the difference package.
    The code as below:
    ExtentReports extentReports;
    ExtentTest extentTest;

    extentReports = ExtentManager.createInstance();
    extentTest = extentReports.createTest(“Test Case 16 is started”);
    And this is for Log:
    extentTest.log(Status.INFO,”Step 01: Login to Website”);

    Report did not show the log: Step 01: Login to Website”

    Please help to correct me if having any wrong step

    Thanks

    Reply
    • It is better to debug it. First, remove all the lines in onTestSkipped method then add the current lines sequentially to find the problematic line and will not use it if it is not mandatory in your project.

      Reply
      • Dear Onur Baskirt,

        Please find the scenario below
        @BeforeSuite — skip if the runflag is N, but what happens a null pointer exception occurs and it is printing as below

        12-340-2018 15:08:35 LoginPageTest.java INFO [main] testcases.LoginPageTest 48 – ————-> SuiteToRunFlag: false
        Extent Reports Version 3 Test Suite started!
        LoginPageTitleTest skipped!
        LoginPageTitleTest failed!
        Extent Reports Version 3 Test Suite is ending!
        java.lang.NullPointerException
        at com.freecrm.ExtentReportListener.MyListener.onTestFailure(MyListener.java:46)
        at org.testng.internal.TestListenerHelper.runTestListeners(TestListenerHelper.java:67)
        at org.testng.internal.Invoker.runTestListeners(Invoker.java:1388)
        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1041)
        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
        at org.testng.TestRunner.privateRun(TestRunner.java:648)
        at org.testng.TestRunner.run(TestRunner.java:505)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
        at org.testng.SuiteRunner.run(SuiteRunner.java:364)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
        at org.testng.TestNG.runSuites(TestNG.java:1049)
        at org.testng.TestNG.run(TestNG.java:1017)
        at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
        at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
        at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)

        I am not sure why it skips and again it fails the same test case when i use Skip Exception in @beforesuite?

        Reply
  4. Dear Onur Baskirt,

    Question : How do I print all my skipped tests in the html Extent Report.

    1. First, I am checking my login function is success in @BeforeClass.
    2. If login success > then I am comfortable in executing my TestNG tests….
    3. My actual query is > If login is NOT-Success, then I want to skip all my tests that are present in the class file.

    How do I write/list all my skipped tests to my extent html file ??

    Below is a sample rough code where I tried to explain my query….

    @BeforeClass
    public void setup()
    {
    if (!LoginSucess(driver))
    {
    throw new SkipException(“Login is not-sucessful…..Hence Skipping the remaing Tests”);
    }
    }

    @Test
    public void test01(){
    elogger = Reporter.extent.startTest(Thread.currentThread().getStackTrace()[1].getMethodName());
    elogger.log(LogStatus.INFO, “Hello test01”);
    }

    @Test
    public void test02(){
    elogger = Reporter.extent.startTest(Thread.currentThread().getStackTrace()[1].getMethodName());
    elogger.log(LogStatus.INFO, “Hello test02”);
    }

    @AfterMethod
    public void getResult(ITestResult result) throws Exception {

    getResultAfterTestExecution(result);

    }

    public static void getResultAfterTestExecution(ITestResult result) throws Exception {

    if (result.getStatus() == ITestResult.FAILURE) {

    //Writing the assert error message
    elogger.log(LogStatus.FAIL, result.getThrowable());

    // To add it in the extent report
    elogger.log(LogStatus.FAIL, elogger.addScreenCapture(screenshotPath));

    } else if (result.getStatus() == ITestResult.SKIP) {

    elogger.log(LogStatus.SKIP, “Test Case is Skipped >> ” + result.getName());

    }

    try {
    elogger.log(LogStatus.INFO, “*************** TEST ENDS ***************”);
    } catch (Exception e) {
    // TODO: handle exception
    }

    extent.endTest(elogger);

    }

    Reply
  5. As extent report 4 is released can we have updated code latest version. The current code doesnot include exception logs in extent report.

    Reply
    • Thanks for the update Siddharth. I am in a very complicated project thus I can’t find time to play new tools and writing articles. But Canberk Akduygu is supporting. MAybe he will update the article.

      Reply
  6. Hi Onur Baskirt,

    I have downloaded the project to my local and ran it through mvn test command.
    But reports are not generated.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.