Reputation: 161
I have tried the example of JUnit listener given in the example in link
MyRunner.class
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);
}
}
JUnitExecutionListener.class
public class JUnitExecutionListener extends RunListener {
@Override
public void testRunStarted(Description description) throws Exception {
System.out.println("Number of tests to execute: " + description.testCount());
}
@Override
public void testRunFinished(Result result) throws Exception {
System.out.println("Number of tests executed: " + result.getRunCount());
}
@Override
public void testStarted(Description description) throws Exception {
System.out.println("Starting: " + description.getMethodName());
}
@Override
public void testFinished(Description description) throws Exception {
System.out.println("Finished: " + description.getMethodName());
}
@Override
public void testFailure(Failure failure) throws Exception {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
@Override
public void testAssumptionFailure(Failure failure) {
System.out.println("Failed: " + failure.getDescription().getMethodName());
}
@Override
public void testIgnored(Description description) throws Exception {
System.out.println("Ignored: " + description.getMethodName());
}
}
I have 3 tests as below
Sample1Test.class
@RunWith(MyRunner.class)
public class Sample1Test {
@Test
public void step1() {
System.out.println("Sample1Test step1");
}
}
Sample2Test.class
@RunWith(MyRunner.class)
public class Sample2Test {
@Test
public void step1() {
System.out.println("Sample2Test step1");
}
}
Sample3Test.class
@RunWith(MyRunner.class)
public class Sample3Test {
@Test
public void step1() {
System.out.println("Sample3Test step1");
}
}
On console I am getting log below,
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.demo.test.Sample1Test
Number of tests to execute: 1
Starting: step1
Sample1Test step1
Finished: step1
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.064 sec
Running com.demo.test.Sample2Test
Number of tests to execute: 1
Number of tests to execute: 1
Starting: step1
Starting: step1
Sample2Test step1
Finished: step1
Finished: step1
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec
Running com.demo.test.Sample3Test
Number of tests to execute: 1
Number of tests to execute: 1
Number of tests to execute: 1
Starting: step1
Starting: step1
Starting: step1
Sample3Test step1
Finished: step1
Finished: step1
Finished: step1
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec
Number of tests executed: 3
Number of tests executed: 3
Number of tests executed: 3
Why JUnitExecutionListener methods are getting called twice for second test and thrice for the third abd so on ? Can we have a fix for this so that each method should call only once ?
Note : I am using junit-4.12
Upvotes: 3
Views: 1280
Reputation: 1
I had the same issue and I fixed it using a maven-surefire-plugin
you can register your custom JUnit listener by adding the below snippet in the maven-surefire plugin in pom.xml. No need to use a custom runner class and @RunWith annotation
<properties>
<property>
<name>listener</name>
<value>path.to.listener.class</value>
</property>
</properties>
Upvotes: 0
Reputation: 4305
RunNotifier is shared among all the children: org.junit.runners.ParentRunner#runChildren
. It basically means that every time method "run" is invoked for one of your runners, the listener is added to the already existing RunNotifier object that may contain your listener already.
There are two ways I see to address the issue:
Remove your listener after the invocation of method run. Like this:
super.run(notifier);
notifier.removeListener(listener);
Hope it was helpful.
Upvotes: 1