【问题标题】:Why RunListener class testRunStarted() method calling multiple times for a single test in JUnit?为什么 RunListener 类 testRunStarted() 方法多次调用 JUnit 中的单个测试?
【发布时间】:2017-12-10 15:19:03
【问题描述】:

我已经尝试了link中示例中给出的JUnit监听器示例

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());
}
}

我有 3 个测试如下

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");
}
}

在控制台上,我得到了下面的日志,

-------------------------------------------------------
 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

为什么 JUnitExecutionListener 方法在第二次测试中被调用两次,在第三次 abd 中被调用三次,依此类推?我们能否解决这个问题,让每个方法只调用一次?

注意:我使用的是 junit-4.12

【问题讨论】:

  • 该死,看起来在每个测试中您都在重新添加 new JUnitExecutionListener()MyRunner.class
  • @AntJavaDev 我们可以为所有类只添加一次监听器吗?

标签: java junit


【解决方案1】:

RunNotifier 在所有孩子之间共享:org.junit.runners.ParentRunner#runChildren。这基本上意味着每次为您的跑步者之一调用方法“run”时,侦听器都会添加到可能已经包含您的侦听器的现有 RunNotifier 对象中。

我认为有两种方法可以解决这个问题:

  1. 制作您的监听器单例对象或将其存储在静态字段中,然后在添加之前检查它是否已在列表中。
  2. 在调用方法 run 后删除您的侦听器。像这样:

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

希望对您有所帮助。

【讨论】:

  • 第一个成功了,我将所有侦听器存储在一个静态集中。另外,我注意到调用 removeListener(listener) 并没有在侦听器中执行 testRunFinished() 。由于和testRunFinished()有关系,所以没有使用第二种方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多