0 votes
1 view
in Devops and Agile by (19.8k points)

When my test case fails, especially on our build server, I want to take a picture / screenshot of the screen to help me debug what happened later on. I know how to take a screenshot, but I was hoping for a way in JUnit to call my takeScreenshot() method if a test fails, before the browser is closed.

No, I don't want to go edit our bazillions of tests to add a try/catch. I could maybe, just possibly be talked into an annotation, I suppose. All of my tests have a common parent class, but I can't think of anything I can do there to solve this.

Ideas?

1 Answer

0 votes
by (63.4k points)

With the MethodRule of JUnit, we can prevent or stop failed unit tests before JUnit passes/dispatches the results. This is the perfect lifecycle event to take the opportunity to take a screenshot of why the test failed.

 

package com.memorynotfound.test;

 

import java.io.File;

import java.io.IOException;

import java.util.UUID;

 

import org.apache.commons.io.FileUtils;

import org.junit.rules.MethodRule;

import org.junit.runners.model.FrameworkMethod;

import org.junit.runners.model.Statement;

import org.openqa.selenium.OutputType;

import org.openqa.selenium.TakesScreenshot;

import org.openqa.selenium.WebDriver;

 

public class ScreenShotOnFailure implements MethodRule {

 

    private WebDriver driver;

 

    public ScreenShotOnFailure(WebDriver driver){

        this.driver = driver;

    }

 

    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {

        return new Statement() {

            @Override

            public void evaluate() throws Throwable {

                try {

                    statement.evaluate();

                } catch (Throwable t) {

                    // only when a test fails exception will be thrown.

                    captureScreenShot(frameworkMethod.getName());

                    // rethrow to allow the failure to be reported by JUnit

                    throw t;

                }

            }

 

            public void captureScreenShot(String fileName) throws IOException {

                File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);

                fileName += UUID.randomUUID().toString();

                File targetFile = new File("/tmp/" + fileName + ".png");

                FileUtils.copyFile(scrFile, targetFile);

            }

        };

    }

}

Apply The rule in Selenium Test

We can include our custom MethodRule by annotating it with @Rule. Then sit back and see the magic happen.

 package com.memorynotfound.test;

 

import org.junit.AfterClass;

import org.junit.BeforeClass;

import org.junit.Rule;

import org.junit.Test;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.firefox.FirefoxDriver;

import java.io.IOException;

 

import static org.junit.Assert.assertTrue;

 

public class ScreenShotTest {

 

    private static WebDriver driver;

 

    @Rule

    public ScreenShotOnFailure failure = new ScreenShotOnFailure(driver);

 

    @BeforeClass

    public static void setUp(){

        driver = new FirefoxDriver();

    }

 

    @Test

    public void testTakeScreenShot() throws IOException {

        driver.get("https://intellipaat.com/");

        assertTrue(false);

    }

 

    @AfterClass

    public static void cleanUp(){

        if (driver != null){

            driver.close();

            driver.quit();

        }

    }

}

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...