How to check if a Test has failed using JUnit?

This blog introduces the JUnit TestWatcher Class. We can use this to detect the Status of a Test Case, and if it has failed, we can then invoke a Method to do something – in this case, report the error and take a screenshot.

There are other approaches to this, but the approach detailed here would be used instead of the usual JUnit @After annotation, and is useful as it will be invoked on any error.

The TestWatcher class Methods

Method Use
succeeded Invoked when a test succeeds
failed Invoked when a test fails
skipped Invoked when a test is skipped due to a failed assumption.
starting Invoked when a test is about to start
finished Invoked when a test method finishes (whether passing or failing)

more details about the TestWatcher Class can be found at: https://junit.org/junit4/javadoc/4.12/org/junit/rules/TestWatcher.html

Example Script

So here is an example with two test cases, using the @Before and @Test JUnit annotations, but instead of an @After block, we will use the TestWatcher finished Method instead.

This example uses Selenium WebDriver & JUnit

/*
 * Example of using the TestWatcher Class to capture a screenshot if
 * a Test case fails
 * https://junit.org/junit4/javadoc/4.12/org/junit/rules/TestWatcher.html
 */
package simplewd;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;

import org.junit.Before;
import org.junit.Test;

import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;

import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.io.FileHandler;

public class SimpleJUWDTest {

	WebDriver driver;

	@Rule
	public final TestRule watchman = new TestWatcher() {
		@Override
		public Statement apply(Statement base, Description description) {
			return super.apply(base, description);
		}
		// This method gets invoked if the test fails for any reason:
		@Override
		protected void failed(Throwable e, Description description) {
                        // Print out the error message:
			System.out.println(description.getDisplayName() + " " + e.getClass().getSimpleName() + "\n");
		        // Now you can do whatever you need to do with it, for example take a screenshot	
                        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);			
			try {
				File currPath = new File(new JFileChooser().getFileSystemView().getDefaultDirectory().toString() + "\\screenshot.png");
				System.out.println("Screenshot at: " + currPath.toString());
				FileHandler.copy(scrFile,  currPath );
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		// This method gets called when the test finishes, regardless of status
		// If the test fails, this will be called after the method above
		@Override
		protected void finished(Description description) {
			if (driver != null)
				driver.quit();
		}
	};

	
	
	@Before
	public void setUp() throws Exception {
		driver = new ChromeDriver(); //instantiate a browser
		driver.get("https://www.edgewordstraining.co.uk/webdriver2");
	}


	@Test
	public void test() throws InterruptedException {
		driver.findElement(By.partialLinkText("Login")).click();
		driver.findElement(By.id("username")).sendKeys("Edgewords");
		driver.findElement(By.id("password")).sendKeys("edgewords123");
		driver.findElement(By.linkText("Submit")).click();
		Thread.sleep(2000);
		assertTrue (driver.findElement(By.linkText("Add Record")).isDisplayed());
	}
	
	@Test
	public void nextTest() {
		System.out.println("This is test two");
		assertTrue (true);
	}

}

Obviously, in the real-world we could add this TestWatcher to a Base Class, and then inherit into our Test Classes, just like we would with the @Before and @After blocks, so we would only have to write this code once.

About Edgewords

Edgewords is a Training provider, specializing in Automated Testing Tools.

For Selenium WebDriver Java Training, please see our Selenium Training Pages