How to implement RunListener a JUnit Listener example
In this example we will show you how you can add a JUnit Listener to your test cases. This JUnit Listener can listen to events of JUnit lifecycle. We can add this listener by creating a custom Runner. Then we use this runner with the @RunWith
annotation which will register our JUnit Listener to the test case.
Create JUnit Listener
We can extend the org.junit.runner.notification.RunListener
class and override the listener methods to implement.
package com.memorynotfound.test;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
public class JUnitExecutionListener extends RunListener {
public void testRunStarted(Description description) throws Exception {
System.out.println("Number of tests to execute: " + description.testCount());
}
public void testRunFinished(Result result) throws Exception {
System.out.println("Number of tests executed: " + result.getRunCount());
}
public void testStarted(Description description) throws Exception {
System.out.println("Starting: " + description.getMethodName());
}
public void testFinished(Description description) throws Exception {
System.out.println("Finished: " + description.getMethodName());
}
public void testFailure(Failure failure) throws Exception {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
public void testAssumptionFailure(Failure failure) {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
public void testIgnored(Description description) throws Exception {
System.out.println("Ignored: " + description.getMethodName());
}
}
Create Custom JUnit Runner
We need to add the listener to the test execution of JUnit. We can add the listener by calling the RunNotifier.addListener()
method. This will register our JUnit Listener. Don’t forget to execute the super.run()
method, otherwise your JUnit test will not start.
package com.memorynotfound.test;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public class MyRunner extends BlockJUnit4ClassRunner {
public MyRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override public void run(RunNotifier notifier){
notifier.addListener(new JUnitExecutionListener());
notifier.fireTestRunStarted(getDescription());
super.run(notifier);
}
}
Test JUnit Listener
Now we need to register our custom runner to our test cases. We can configure this with the @RunWith()
annotation.
package com.memorynotfound.test;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertTrue;
@RunWith(MyRunner.class)
public class RunListenerTest {
@Test
public void testListener(){
}
@Test
public void testFalseAssertion(){
assertTrue(false);
}
@Ignore
@Test
public void testIgnore(){
}
@Test
public void testException(){
throw new RuntimeException();
}
}
JUnit Listener example output
Now when we execute our test cases we receive the following output. These Unit test will fail, I know. They are just for showing you which error could occur.
Starting: testException
Failed: testException
Finished: testException
Ignored: testIgnore
Starting: testFalseAssertion
Failed: testFalseAssertion
Finished: testFalseAssertion
Starting: testListener
Finished: testListener
Number of tests executed: 3
Great tutorial!
Note that super.run(Notification notification) is actually the main execution method and is called only once so make sure you attach a Listener before calling it.
Great, thanks.
But I’ve got a question, this way it produces a report for each annotated class. How to avoid this and only have one report ?
Great,
Why is the “testRunStarted” method not called?
Background:
I am currently creating integration tests with JUnit. I want to setup the environment (e.g. init database with some data) in the
testRunStarted() method.
i have this scenario. I have declared a member variable in JUnitExecutionListener which is populated in testRunStarted(). Now i want to use this variable in one of Test classes(RunListenerTest in this case). How can i do that. There seems to be no way i can access any member of the listener in my tests. please help