JUnit 4的@Suite,传递数据,@ Rule并弃用@Before和@After

时间:2011-02-04 00:55:10

标签: unit-testing junit annotations integration-testing suite

我正在使用一些遗留测试代码,该代码利用TestSetup类围绕包含测试的测试套件设置和拆除服务器。我已经将类转换为使用junit注释,并尝试使用@Suite和@ Suite.Classes注释来定义套件。但是我撞墙了。

旧版本的测试扩展TestSetup以循环遍历所有实例化的测试类,并将对服务器对象的各种引用注入其中。一个示例是对Spring框架Web上下文的引用。

我的问题是使用注释我无法看到在执行测试之前如何将fixture数据传递给实例化的测试类。

我已经研究了新的@Rule和MethodRule技术,但(坦率地说)它们似乎只是一个复杂但有限的解决方案,解决了一个不太清楚的问题。无论如何,我看不出他们如何解决我的问题。另一个问题是JUnit作者似乎打算最终从JUnit中删除@ Before / @ After概念。

那么有没有人知道如何将带有@Suite注释的类的数据传递给Suite类运行的每个测试?

2 个答案:

答案 0 :(得分:2)

  

我的问题是使用了   注释我看不出如何通过   夹具数据到实例化的测试   测试执行前的类。

JUnit4风格的测试套件比JUnit3风格的测试套件更受限制。我听说过这方面的抱怨,但我不知道官方解决方案。我认为可能会有一些第三方解决方案试图解决这个问题。关于你的特定问题,我认为你不能从JUnit4风格的套件访问测试实例,因为JUnit4在方法运行之前就实例化了一个测试。

最简单的方法是继续使用JUnit3风格的套件。它们应该可以与JUnit4一起运行。使用管理共享资源的一个缺点 套件是你不能再单独运行测试类了。另一方面,如果测试类无论如何都需要一起运行(可能按特定顺序),它可能是一个有效的解决方案。

另一种方法是从内到外解决共享资源问题:在您的情况下,测试类将使用@Rule声明他们需要服务器存在。第一次执行规则时,它启动服务器,将相关信息保存在静态字段中,并执行准备测试所需的任何操作。例如,它可以注入一些测试的字段,或者它可以只允许测试使用规则的API来获取所需的信息。下次执行规则时,它会跳过“启动服务器”步骤。是的,静态是邪恶的,但它有时是解决JUnit限制的唯一方法。 (我不会在这里触及使用其他测试框架的主题。)

从内到外的方法的一大优势是它允许您直接运行测试类(无需通过套件)并且彼此独立。缺点是它可能更难实现,并且很难拆除非内存资源(在您的情况下:关闭服务器)。要完成后者,您必须使用JVM关闭挂钩,因为JUnit不提供足够的回调。虽然这可能会起作用(因为构建工具和IDE通常在每次测试运行时使用单独的JVM),但它仍然很难看。

第三种方法是让您的Ant / Maven / Gradle /任何构建在运行测试之前/之后设置/拆除公共资源。同样,这比内向外方法更不灵活和方便,并提出了如何将信息从构建传递到运行测试的JVM(如果需要)的问题。 Maven Cargo plugin是此方法的典型示例。

最后但并非最不重要的是,您可以尝试务实,并在每个测试类中启动/停止服务器一次。这很容易实现,但在您的情况下可能会或可能不充分(例如,它可能太耗时)。

  

我调查了新的@Rule和   MethodRule技术,但(坦率地说)   它们似乎很复杂,但是   解决问题的有限解决方案   不太清楚

规则是编写模块化和可重用JUnit扩展的一种方法。比使用基类更好,你很快就会遇到单继承问题。这对于发布JUnit扩展的库来说更为重要。

  

另一个值得关注的问题   似乎是JUnit的作者   意图最终删除   @ Before / @来自JUnit的概念。

你在哪里听到的?你是不是把它与xUnit.net混淆了,强烈反对使用设置/拆解方法?无论如何,在测试之前或之后执行一些操作是规则最重要的用例之一,所以我认为你不应该担心。

答案 1 :(得分:0)

JUnit 4.9正在以构建器的形式为此做一个更好的解决方案,但我认为在此之前最简洁(虽然有点难以实现)的方法来解决这个问题是制作一个自定义的Runner实现(扩展其中一个)现有的)。 @Peter是完全正确的,套件创建比JUnit 3.8有弱点,虽然它也有一些优点。