首页 > 解决方案 > 如何在 JUnit5 中定义优先级

问题描述

我在 Java 项目中使用 Junit 构建了一些单元测试。唯一的问题是我想定义测试的顺序/优先级。我的意思是...我@BeforeAll用来执行第一个测试,这是登录过程并获得登录后功能的访问权限。但在那之后,我想运行另一个特定的测试。

然后剩下的...

我检查并有一个使用@Order()注释的选项,但我的想法不是要像这样订购每个测试......我只想先运行登录,然后运行我需要运行所有其他测试的测试。因此,在前两个测试之后,其他测试的顺序无关紧要。

标签: javajunitjunit5

解决方案


首先,让单元测试依赖于其他单元测试通常是糟糕的设计。JUnit 5 用户指南提到了这一点:

尽管真正的单元测试通常不应该依赖于它们的执行顺序,但有时需要强制执行特定的测试方法执行顺序——例如,在编写集成测试功能测试时,测试的顺序是重要,尤其是与@TestInstance(Lifecycle.PER_CLASS).

考虑一下您正在做的是测试还是设置。如果登录操作只是为您的测试设置,那么您应该在使用@BeforeAllor注释的方法中执行此操作@BeforeEach,以您的上下文中更有意义的为准。@AfterAll之后,您可能需要使用或进行清理@AfterEach,具体取决于您使用的“注释前”。

如果您实际上是在尝试测试登录代码,请尝试将这些测试与其他测试分开。您可以通过将它们移动到单独的类文件中,甚至利用@Nested类(如果合适的话)来做到这一点。您应该使用登录,而不是让您以后的测试需要真正的登录。换句话说,模拟以后测试所需的依赖项。这将消除测试间依赖情况。并且不要害怕为每个测试重新“登录”(例如使用);如果您使用的是模拟,这应该不会太贵。@BeforeEach

TestWatcher注意:从 JUnit 5.4 开始,如果以前的测试使用扩展失败,您甚至可以中止一些测试,如本问答中所述。但是,使用这种方法似乎更适合集成测试而不是单元测试


也就是说,你想要的应该是可能的。您提到@Order但随后又说您对使用它犹豫不决,因为您不想订购每种方法,只需确保两个测试在所有其他测试之前运行即可。您不必为每个方法添加注释。如果您查看 的文档MethodOrderer.OrderAnnotation,您会看到:

MethodOrderer根据@Order注释对方法进行排序。

任何分配了相同顺序值的方法都将被任意相邻排序。

任何未使用注释的方法@Order都将被分配一个默认顺序值,Integer.MAX_VALUE该值将有效地导致它们出现在排序列表的末尾。

Order.value()

元素根据优先级排序,其中较低的值比较高的值具有更高的优先级。例如,Integer.MAX_VALUE具有最低优先级。

这意味着你只需要注释你的两个测试,@Order剩下的就不用管了。所有没有注释的测试方法@Order都将按任何顺序运行,但在前两个测试之后。

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class MyTests {

    @Test
    @Order(1)
    void firstTest() {}

    @Test
    @Order(2)
    void secondTest() {}

    @Test
    void testFoo() {}

    @Test
    void testBar() {}

    // other tests...

}

推荐阅读