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();
}
}
}