Capture Screenshot for Failed Tests in TestNG
Capture screenshot for failed tests in testNG will discuss about how to take a screenshot when a test case fails while executing the test suite. The screenshot will give the information about on which screen the script got failed during the execution. Then we can easily identify the issue by looking into the screenshot.
To achieve this we need to write 2 utility classes. One is to take the screenshot and another is to listen to the test status result and take the screenshot accordingly. For this we need to use Listeners in the testNG. We need to implement the ITestListener from the testNG in order to get the status of the test case. If the test case is fail then it will track that information and then will take the screenshot using the screenshot utility.
Below will see how can we achieve this. For this, we need to write 4 different classes. One is MainTest which will be used to initiate the WebDriver as we need to use the same webdriver instance across our framework. So, whenever there is a need of using webdriver instance then that class will extend this MainTest. Then we can maintain a single webdriver instance across our project.
Second is GetScreenshot which will be used to take the screenshot when there is a need. This is not only useful for the failed tests. If you want to capture screenshot anywhere in the project then you can use this utility to take the screenshot. But here we are using this in the listener as we need to take the screenshot for the failed tests.
Third is ListenerTest which will be used to listen the status of our test cases and act accordingly. For this we need to implement ITestListener interface from the testNG. And we need to use this listener in the testng.xml file to track the test cases status. Once there is any failure in the test case then it will call the listener and we have to mention to take the screenshot for the failed test.
Here, we need to implement all the methods which are available in the ITestListener interface. And it is not mandatory to implement all the methods but atleast we need to mention those methods without any logic. Here the useful method is onTestFailure. And this method contains the logic to capture the screenshot.
Fourth is CaptureScreenshotTests which is the class contains actual test cases which we are going to execute. Once there is any failure then it will be tracked by the onTestFailure from the listener class and then it will take the screenshot for the same.
Below program is to initialize the webdriver:
package com.automationtesting.screenshot; import org.openqa.selenium.WebDriver; public class MainTest { public static WebDriver driver; }
Below program is to capture the screenshot:
package com.automationtesting.screenshot; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; public class GetScreenshot extends MainTest { public static String capture(String screenshotName) throws IOException { TakesScreenshot ts = (TakesScreenshot) driver; File source = ts.getScreenshotAs(OutputType.FILE); String dest = System.getProperty("user.dir") + "/ErrorScreenshot/" + screenshotName + ".png"; File destination = new File(dest); FileUtils.copyFile(source, destination); return dest; } }
Below program is to implement the listener:
package com.automationtesting.screenshot; import java.io.IOException; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; public class ListenerTest extends MainTest implements ITestListener { @Override public void onTestStart(ITestResult result) { // TODO Auto-generated method stub } @Override public void onTestSuccess(ITestResult result) { // TODO Auto-generated method stub } @Override public void onTestFailure(ITestResult result) { try { GetScreenshot.capture(result.getName()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onTestSkipped(ITestResult result) { // TODO Auto-generated method stub } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult result) { // TODO Auto-generated method stub } @Override public void onStart(ITestContext context) { // TODO Auto-generated method stub } @Override public void onFinish(ITestContext context) { // TODO Auto-generated method stub } }
Below program is for actual test cases:
package com.automationtesting.screenshot; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.Test; public class CaptureScreenshotTests extends MainTest { @Test public void captureScreenshot() { System.setProperty("webdriver.firefox.marionette", "D:\\drivers\\geckodriver-0.10.0\\geckodriver.exe"); driver = new FirefoxDriver(); driver.get("http://automationtesting.in"); String title = driver.getTitle(); Assert.assertEquals("Home - Automation Test", title); driver.close(); } }
In the above program it will try to assert the page title. But we intentionally failing this assert to capture the screenshot for this failure.
Below program is to execute the test cases from testng.xml file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite"> <listeners> <listener class-name="com.automationtesting.screenshot.ListenerTest"></listener> </listeners> <test name="Test"> <classes> <class name="com.automationtesting.screenshot.CaptureScreenshot"/> </classes> </test> </suite>
Once you execute the above xml file then it capture the screenshot and it will place that in the ErrorScreenshot folder with the method name in the current project folder structure.
This way we can achieve this functionality.
Please watch You tube video for better understanding.