Beside the exception / failure information, it is almost always helpful for the developers to provide them with additional screenshot of the failed tests.
From JUnit 4.7 the @Rule annotation is introduced which can be used to extend the capabilities of JUnit. With it we can invoke a custom piece of code when a test fails or succeeds.
In this example we will capture a screenshot of a failed test.
Before showing how it is done, we should have a test class at hand. For the following example just download the selenium driver from the page http://seleniumhq.org/download/ and add the jar files to classpath.
package test;
import static org.junit.Assert.assertTrue;
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.WebDriverBackedSelenium;
import org.openqa.selenium.firefox.FirefoxDriver;
import com.thoughtworks.selenium.Selenium;
//This is an example for the usage of ScreenshotTestRule
public class TestWithScreenshotExample {
//
static WebDriver driver;
static Selenium selenium;
// an annotation is used for defining a new rule for Junit
@Rule
public ScreenshotTestRule screenshotTestRule = new ScreenshotTestRule();
@BeforeClass
public static void beforeClass() {
driver = new FirefoxDriver();
selenium = new WebDriverBackedSelenium(driver, "http://www.google.com");
}
@AfterClass
public static void afterClass() {
driver.quit();
}
@Test
public void testThatSucceeds() {
selenium.open("/");
// some text code here
assertTrue(selenium.isTextPresent("This test will pass"));
}
@Test
public void testThatFails() {
selenium.open("/");
//some text code here
assertTrue(selenium.isTextPresent("This test will fail"));
}
// the static driver object will be needed for capturing screenshots
public static WebDriver getDriver() {
return driver;
}
The trick above is to define a new JUnit rule with @Rule annotation.
The class which is used to define the new rule needs to implement the MethodRule interface and to override the apply() function.
package test;
import java.io.File;
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;
class ScreenshotTestRule implements MethodRule {
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) {
// exception will be thrown only when a test fails.
captureScreenshot(frameworkMethod.getName());
// rethrow to allow the failure to be reported by JUnit
throw t;
}
}
public void captureScreenshot(String fileName) {
try {
//
File screenshot = ((TakesScreenshot)TestWithScreenshotExample.getDriver()).getScreenshotAs(OutputType.FILE);
// the screenshots can be moved to a folder for sorting FileUtils.copyFile(screenshot, new File("./screenshot-"+fileName+".png"));
} catch (Exception e) {
// No need to crash the tests if the screenshot fails
}
}
};
}
}
By overwriting the apply() function we can intervene before Junit sends out the test results, and we can insert the screenshot capturing code.
For further information on using the @Rule annotation check out: http://junit.org/junit4/javadoc/4.12/org/junit/Rule.html
Happy screenshot capturing!
Similar Posts from the author:
- Selenium test in Java with Eclipse and JUnit
- Solution for – Could not start Selenium Session : Connection timed out
- Solution for Selenium IDE Export to C# problem
- Solution for Selenium IDE – Your browser doesnt support Xml Http Request
- How To Make Android Screenshots for testing
5 thoughts to “Capturing screenshots of failed tests in Selenium Webdriver + JUnit4”
Thanks for this info. But I use selenium RC for test execution and I prepare my selenium testcases in eclipse using testNG .Can u please provide me the same for my specifications. Or if there is any minor modifications in the above code to fit selenium RC ,can u please let me know that.
Hi
it would be helpful if you can show an example of generating test report of a login failed using selenium and junit
Hi,
I have tried this example, but eclipse say that MethodRule is deprecated, I am using JUit 4.10, are their other approaches to do the same ?
Thanks,
Ostap
Please check out if you use the correct packages.
The junit.framework.* packages are deprecated and the
org.junit.* packages are being used instead.
Hi,
Thanks for the solution. It is working absolutely fine when I have no ErrorCollector rule applied in my test. I want to takes screenshots for every failure added in errorcollector. For example, I have 5 validations in my test and all exceptions are adding into Error collector object. Here I want to capture screenshots for all failed validations in a test. Please suggest.
Thanks
Siva