Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why RunListener class testRunStarted() method calling multiple times for a single test in JUnit?

Tags:

java

junit

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

like image 362
Balu Avatar asked Dec 04 '25 18:12

Balu


1 Answers

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:

  1. Make your listener singleton object or just store it in a static field and then before adding just check whether or not it is already in the list.
  2. Remove your listener after the invocation of method run. Like this:

    super.run(notifier);
    notifier.removeListener(listener);
    

Hope it was helpful.

like image 97
dvelopp Avatar answered Dec 07 '25 06:12

dvelopp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!