TestNG | Use ReportNG

Integrate ReportNG with your TestNG framework. It also provides some settings for Jenkins to integrate the reporting there as well.

Important: This document includes references to third-party products, TestNG and Jenkins. The user interface and usage of third-party products are subject to change without notice. For the latest published information about TestNG, see https://testng.org/doc/documentation-main.html. The user interface and usage of third-party products are subject to change without notice. For the latest published information about Jenkins, see https://www.jenkins.io/doc.

Disable TestNG default listeners and set storage location

The first step is to turn off default listeners for TestNG.

Right click your project in Eclipse and select properties

Next select TestNG on the side bar and check "Disable default listeners". Change your output directory to "/surefire-reports". Lastly click Apply and click OK to close the window.

Dependencies

Now we'll add the appropriate jars to our pom.xml.

Copy
<dependency>
  <groupId>org.uncommons</groupId>
  <artifactId>reportng</artifactId>
  <version>1.1.4</version>
  <exclusions>
    <exclusion>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>com.google.inject</groupId>
  <artifactId>guice</artifactId>
  <version>3.0</version>
</dependency>
<dependency>
  <groupId>velocity</groupId>
  <artifactId>velocity-dep</artifactId>
  <version>1.4</version>
</dependency>        

Additional pom.xml settings (for Jenkins)

Copy
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.18.1</version>
      <configuration>
        <properties>
          <property>
            <name>usedefaultlisteners</name>
            <value>false</value>
          </property>
          <property>
            <name>listener</name>
            <value>org.uncommons.reportng.HTMLReporter,
                                org.uncommons.reportng.JUnitXMLReporter</value>
          </property>
        </properties>
        <workingDirectory>target/</workingDirectory>
      </configuration>
    </plugin>
  </plugins>
</build>

TestNG.xml modifications

You now need to add the appropriate listeners to the testng.xml file. Example below.

Copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="10" verbose="0" configfailurepolicy="skip">
 <listeners>
   <listener class-name="org.uncommons.reportng.HTMLReporter"/>
   <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
 </listeners>     
 
 <test name="Test Chrome implicitNotVisible">
 <parameter name="targetEnvironment" value="Chrome" />
 <parameter name="network" value="" />
 <parameter name="networkLatency" value="" />
   <classes>
     <class name="AmazonTesting.SleepTestSystem">
       <methods>
         <include name="implicitNotVisible" />
       </methods>
     </class>
   </classes>   
 </test>
</suite>

Embed artifacts into reportNG report (Perfecto Reports, Screenshots, etc)

Below you will find a few methods showing how to store screen shots as well as the Perfecto report into your reportNG report.

Copy
public void takeScreen(String text, Boolean addReport) {
               
        log(text, false);

            // set file name and destination for screen shot
            File scrFile = ((TakesScreenshot) driver)
                    .getScreenshotAs(OutputType.FILE);
            DateFormat dateFormat = new SimpleDateFormat(
                    "dd_MMM_yyyy__hh_mm_ssaa");
            String destDir = "./surefire-reports/html/screenshots/";
            new File(destDir).mkdirs();
            String destFile = testName + "_" + target + "_" + getNetwork()
                    + "_Step" + step + "_" + dateFormat.format(new Date())
                    + ".png";

            // copy screen shot to directory for jenkins
            try {
                FileUtils.copyFile(scrFile, new File(destDir + "/" + destFile));
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            log("screenShot: " + destDir + "/" + destFile, false);
            // Display screenshot to ReportNG
            if (addReport) {

                String userDirector = "./screenshots/";
                log("<u><b>||||||" + text + "</b></u><br><a href=\""                        + userDirector + destFile + "\"><img src=\""                        + userDirector + destFile + "\" alt=\"\""                        + "height='100' width='100'/> " + "<br />", addReport);
            }
        
    }


    // writes to console or/and report log
    // boolean controls whether report log is written to
    public void log(String text, Boolean addReport) {
        String newLine = System.getProperty("line.separator");

        if (addReport) {
            final String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
            System.setProperty(ESCAPE_PROPERTY, "false");
            Reporter.log(text.replace("<u><b>||||||", "<u><b>" + testName + "_"                    + target + "_" + getNetwork() + "_Step" + step + "_"));
        } else {
            System.out.println(testName + "_" + target + "_" + getNetwork()
                    + "_Step" + step + "_" + text + newLine);
        }
    }

    // Calls downloadreport, copys the perfecto report to the screen directory
    // boolean will add the report to the TestNG report
    public void downloadReportDisplay(Boolean addReport) throws IOException {

        if (isDevice()) {
            // set file format and destination for report
            DateFormat dateFormat = new SimpleDateFormat(
                    "dd_MMM_yyyy__hh_mm_ssaa");
            String destDir = "./surefire-reports/html/screenshots/";
            new File(destDir).mkdirs();
            String destFile = dateFormat.format(new Date());

            // download report
            downloadReport("pdf", destDir , destFile);
            // Display screenshot to ReportNG
            String userDirector = "./screenshots/";

            String destFileNew = destFile + ".pdf";

            log("perfectoReport: " + userDirector + destFileNew, false);
            if (addReport) {
                log("<a href=\"" + userDirector + destFileNew
                        + "\">Perfecto Report</a><br />", addReport);
            }
        }
    }


    // download report from perfecto
    private void downloadReport(String type, String fileLocation, String file)
            throws IOException {
        if (isDevice()) {        
                // downloads report for remote web driver
                String command = "mobile:report:download";
                Map<String, Object> params = new HashMap<>();
                params.put("type", type);
                String report;                
                    report = (String) getDriver().executeScript(
                            command, params);
                    
                //download to directory for jenkins
                File reportFile = new File(fileLocation + "/" + file + "." + type);
                BufferedOutputStream output = new BufferedOutputStream(
                        new FileOutputStream(reportFile));
                byte[] reportBytes = OutputType.BYTES
                        .convertFromBase64Png(report);
                output.write(reportBytes);
                output.close();    
            }        
    }

Report output using the methods from above. In general, to write to the report all you need to do is the following:

Copy
//report will literally show "<b>text to write</b>"Reporter.log("<b>text to write</b>")

And if you are storing html you need to first tell the logger to NOT escape html characters.

Copy
final String ESCAPE_PROPERTY = "org.uncommons.reportng.escape-output";
            System.setProperty(ESCAPE_PROPERTY, "false");
//text will now be bold on the report
Reporter.log("<b>text to write</b>")

Keep in mind too the use of relative paths for your screenshots and Perfecto report downloads so when running on a build server you don't run into complications. The storage of your Perfecto reports and screenshots needs to have a path to the surefire directory whereas the links in the report needs to to be relative to the directory itself.

Copy
//use this path when storing the downloaded Perfecto Report or screnshot String destDir = "./surefire-reports/html/screenshots/";
//use this path when linking to the screenshots and Perfecto report String userDirector = "./screenshots/";

Lastly if you call the download for the Perfecto report method in a TestNG listener like afterClass or afterMethod the link won't be stored in the report as part of the method. Instead you will need to search in the Log Output section of the report for the link.

A work around for this issue is to pass the ITestResult variable to the Reporters setCurrentTestResult method inside the listener before calling Reporter.log();.

Copy
Reporter.setCurrentTestResult(testResult);