How can I include a failure screenshot to the testNG report

26,885

Solution 1

Yes, you can include the link to your screenshot in testng report.

You need to call org.testng.Reporter.log method to write the hyperlink to the report either by annotating your test class or parent of all testclasses with @Listeners({yourListener.class}) or by adding the listener to your testng.xml.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="default">
  <listeners>
    <listener class-name="ScreenshotListener" />
  </listeners>
  <test name="Test">
    <packages>
      <package name="someTests.*"/>
    </packages>
  </test>
</suite>

You need to first create a Listener class and add it to testng. You can get details for that from testng.org. Search for listener.

Once you create that class, you should write a method in it which overrides the ontestfailure method. The code inside this method will be executed whenever testng identifies a failure.

You can call your screenshot grabbing method and use Reporter.log to put the hyperlink to that screenshot. Then you can find this link under the failed testcases details.

import java.io.*;
import java.util.*;
import java.text.*;
import org.apache.commons.io.FileUtils;

import org.openqa.selenium.*;

import org.testng.*;

public class ScreenshotListener extends TestListenerAdapter {
    @Override
    public void onTestFailure(ITestResult result) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
        String methodName = result.getName();
        if(!result.isSuccess()){
            File scrFile = ((TakesScreenshot)SomeStaticWebDriver.driver).getScreenshotAs(OutputType.FILE);
            try {
                String reportDirectory = new File(System.getProperty("user.dir")).getAbsolutePath() + "/target/surefire-reports";
                File destFile = new File((String) reportDirectory+"/failure_screenshots/"+methodName+"_"+formater.format(calendar.getTime())+".png");
                FileUtils.copyFile(scrFile, destFile);
                Reporter.log("<a href='"+ destFile.getAbsolutePath() + "'> <img src='"+ destFile.getAbsolutePath() + "' height='100' width='100'/> </a>");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Solution 2

Customizing a bit of ExtentReport can give extremely useful report having exception+screenshot captured exactly at time of test failure . Screenshot can be placed alongside exception which user can use to know what was website doing when error occurred.

Report Example enter image description here Test

      @Test (enabled=true)                           
        public void verifySearch() {
       extentlogger = extent.createTest("To verify verifySearch");
      //Your other code here.....
        soft.assertEquals("xxx", "xxxx");
        soft.assertAll();
      }

AfterMethod

     @AfterMethod
     public void getResult(ITestResult result) throws Exception{
      if(result.getStatus() == ITestResult.FAILURE)
     {
        extentlogger.log(Status.FAIL, MarkupHelper.createLabel(result.getThrowable() + 
        " - Test Case Failed", ExtentColor.RED));
    
        try {
        // get path of captured screenshot using custom failedTCTakeScreenshot method
        String screenshotPath = failedTCTakeScreenshot( result);
        extentlogger.fail("Test Case Failed Snapshot is below " + 
      extentlogger.addScreenCaptureFromPath(screenshotPath));
       } catch (InterruptedException e) {
        e.printStackTrace();
        }
      }
     }
Share:
26,885
Tarken
Author by

Tarken

Updated on August 20, 2022

Comments

  • Tarken
    Tarken over 1 year

    currently I am taking screenshots of my test failures this way:

    @AfterMethod(alwaysRun=true)
    public void catchExceptions(ITestResult result){
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
        String methodName = result.getName();
        if(!result.isSuccess()){
            File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
            try {
                FileUtils.copyFile(scrFile, new File((String) PathConverter.convert("failure_screenshots/"+methodName+"_"+formater.format(calendar.getTime())+".png")));
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
    

    Can I include my own screenshots into the TestNG report link or pic? If yes how?

    All I found on that online is the FEST framework. But since I am already taking the screenshots I dont want to use another framework.

  • Tarken
    Tarken over 12 years
    Thanks for the answer. Is there away to place the link/pic in the results? Like under the failed method name or something like that?
  • A.J
    A.J over 12 years
    Yes. You need to first create a Listener class and add it to testng. You can get details for that from testng.org. Search for listener. Once you create that class, you should write a method in it which overrides the ontestfailure method. The code inside this method will be executed whenever testng identifies a failure. You can call your screenshot grabbing method and use Reporter.log to put the hyperlink to that screenshot. Then you can find this link under the failed testcases details.
  • Tarken
    Tarken over 12 years
    Thanks for the quick guide :-) I ll try that when I am back at work.
  • Ondrej Burkert
    Ondrej Burkert over 10 years
    Excellent. Worked like a charm. Fascinating, how such a short description can be helpful;) A bit more details. Extend TestNG TestListenerAdapter, implement onTestFailure as in the question above plus add at the end Reporter.log("<a href='" + screenshotFile.getAbsolutePath() + "'>screenshot</a>");, annotate your test class or parent of all testclasses with @Listeners({yourListener.class}). And you're done.
  • Ziska
    Ziska about 10 years
    @A.J My approach was just as you had suggested (I added my listener to testng.xml instead annotating my base test class with @Listener). But my testNG report does not attach the screenshots. Instead it treats <img> as text. My Reporter.log entry looks as: Reporter.log("<img src=\"file://" + fullFileName + "\" alt=\"\" height='100' width='100' /><br/>"); Am I missing something?
  • Ziska
    Ziska about 10 years
    Actually, the screenshot IS attached to index.html. But the img tag is still treated as text in emailable-report.html. I would prefer to have the screenshots in emailable-report.html so I can email the screenshots along with the test results. How can I achieve this? How is this report different?
  • A.J
    A.J about 10 years
    @Harini I am assuming you are running this test from eclipse using testNG plugin. You need to go to properties of your project, then to testNG section and check the option-use project testng jar. Your issue will be resolved
  • Ziska
    Ziska about 10 years
    @A.J Thanks for the quick reply. I actually run my tests using maven. Do I need to make any changes to my POM.xml?
  • A.J
    A.J about 10 years
    @Harini Sorry i don't know how to make that change in Maven project.
  • Cagy79
    Cagy79 over 9 years
    @A.J My <img> tags are also displayed as text. I changed the setting in Eclipse that you mentioned but I see no changes in my emailable report. Any thoughts on that? Thanks!
  • A.J
    A.J over 9 years
    @Cagy79 If you have selenium-standalone.jar and testng.jar in your library path, you need to change the ordering of jar files. I assume that selenium.jar has an older version of testNG which is causing this weird behavior.
  • Shivam Mishra
    Shivam Mishra almost 3 years
    Doesn't answer the original question