2

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

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

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

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

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

4

2 回答 2

2

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

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

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

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

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

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

最后但并非最不重要的一点是,您可以尝试务实并在每个测试类中启动/停止服务器一次。这实现起来非常简单,但在您的情况下可能合适,也可能不合适(例如,它可能太耗时)。

我已经研究了新的@Rule 和 MethodRule 技术,但(坦率地说)它们似乎是一个复杂但有限的解决方案,对于一个不太清楚的问题

规则是编写模块化和可重用 JUnit 扩展的一种方式。比使用基类要好得多,因为基类很快就会遇到单继承问题。这与提供 JUnit 扩展的库更相关。

另一个担忧是,JUnit 作者似乎打算最终从 JUnit 中删除 @Before/@After 概念。

你是从哪里听来的?您不会将此与xUnit.net混淆,后者强烈反对使用设置/拆卸方法?无论如何,在测试之前或之后执行一些操作是规则最重要的用例之一,所以我认为您不必担心。

于 2011-02-04T03:29:27.870 回答
0

JUnit 4.9 正在以构建器的形式为此提供更好的解决方案,但我认为在此之前解决此问题的最干净(虽然有点难以实现)的方法是制作自定义 Runner 实现(扩展现有的一个) . @Peter 非常正确,套件创建相对于 JUnit 3.8 有弱点,尽管它也有一些优点。

于 2011-02-04T04:27:47.010 回答