16

我正在使用 jUnit 来管理访问数据库的应用程序的集成测试。因为设置测试数据是一项耗时的操作,所以我一直在@BeforeClass方法中这样做,每个测试类只执行一次(与@Before方法相反,每个测试方法运行一次)。

现在我想为数据层的配置尝试一些不同的排列,在每个不同的配置上运行我的所有测试。这似乎是对Parameterized测试运行器的自然使用。问题是,Parameterized向类构造函数提供参数,并且该@BeforeClass方法是抽象的并且在类构造函数之前被调用。

几个问题,

是否为每个参数排列Parameterized调用该@BeforeClass方法,还是只调用一次?

如果该@BeforeClass方法被重复调用,是否有某种方法可以从它内部访问参数值?

如果这些都不是,人们建议作为解决这个问题的最佳替代方法是什么?

4

5 回答 5

3

我认为您将需要一个自定义测试运行器。我遇到了同样的问题(需要使用多个昂贵的配置运行相同的测试)。您需要一种方法来参数化设置,可能使用类似于 Parameterized 运行器使用的 @Parameter 注释,但在静态成员字段而不是实例字段上。自定义运行器必须找到所有带有 @Parameter 注释的静态成员字段,然后每个静态 @Parameter 字段运行一次测试类(可能使用基本的 BlockJunit4ClassRunner)。@Parameter 字段应该是@ClassRule。

Andy on Software 在开发自定义测试运行程序方面做得很好,他在此处此处的这些博客文章中解释得非常清楚。

于 2013-11-25T21:15:27.437 回答
1

@BeforeClass 在您的示例中仅调用一次。考虑到这个名字,这是有道理的——上课前!

如果您的测试需要不同的数据,我可以想到两种选择:

  1. 在 @Before 中设置该数据,使其特定于测试
  2. 将要使用相同数据运行的测试分组到单独的测试类中,并为每个测试类使用 @BeforeClass。
于 2012-06-27T02:32:07.473 回答
0

您可以在测试类的构造函数中调用此初始化逻辑。跟踪静态变量中使用的最后一个参数。当它改变时,为新参数设置类。

我想不出AfterClass的等价物。

于 2013-02-12T22:42:16.453 回答
0

这是一个老问题,但我只需要解决一个可能类似的问题。我现在使用下面的解决方案,它本质上是使用通用抽象基类实现 TREE(更新)答案,以避免在需要此机制时出现重复。

具体测试将提供一个 @Parameters 方法,该方法返回一个可迭代的单元素数组,每个数组包含一个 Supplier< T >。然后,根据具体测试方法所需的实际输入,这些供应商只执行一次。

@RunWith(Parameterized.class)
public class AbstractBufferedInputTest<T> {

private static Object INPUT_BUFFER;

private static Object PROVIDER_OF_BUFFERED_INPUT;

private T currentInput;

@SuppressWarnings("unchecked")
public AbstractBufferedInputTest(Supplier<T> inputSuppler) {
    if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) {
        INPUT_BUFFER = inputSuppler.get();
        PROVIDER_OF_BUFFERED_INPUT = inputSuppler;
    }
    currentInput = (T) INPUT_BUFFER;
}

/**
 * 
 * @return the input to be used by test methods
 */
public T getCurrentInput() {
    return currentInput;
}

}
于 2015-09-23T07:31:08.613 回答
-1

您可以在 @Before 方法中进行初始化,写入实例变量但测试 null。

@RunWith(value = Parameterized.class)
public class BigThingTests {
  private BigThing bigThing;

  @Before
  public void createBitThing() {
    if (bigThing == null) {
      bigThing = new BigThing();
    }
  }

...
}

BigThingTests为每组参数创建一个新实例,并bigThing在每个新实例中设置为 null。运行器是Parameterized单线程的,因此您不必担心多次初始化。

于 2013-02-01T16:50:25.310 回答