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
Comments are closed.