我想以特定的顺序执行@Test注释的测试方法。

例如:

public class MyTest {
    @Test public void test1(){}
    @Test public void test2(){}
}

我想确保每次运行MyTest时都在test2()之前运行test1(),但我找不到@Test(order=xx)这样的注释。

我认为这对JUnit来说是非常重要的功能,如果JUnit的作者不想要订单功能,为什么?


当前回答

迁移到TestNG似乎是最好的方法,但是我没有看到jUnit的明确解决方案。以下是我为jUnit找到的最有可读性的解决方案/格式:

@FixMethodOrder( MethodSorters.NAME_ASCENDING ) // force name ordering
public class SampleTest {
    @Test
    void stage1_prepareAndTest(){};

    @Test
    void stage2_checkSomething(){};

    @Test
    void stage2_checkSomethingElse(){};

    @Test
    void stage3_thisDependsOnStage2(){};

    @Test
    void callTimeDoesntMatter(){}
}

这确保stage2方法在stage1方法之后和stage3方法之前被调用。

附注:我觉得这种方法比jUnit 5.5 @Order注释更好,因为它为读者提供了更好的标记。

其他回答

(尚未发布的)更改https://github.com/junit-team/junit/pull/386引入了@SortMethodsWith。https://github.com/junit-team/junit/pull/293至少使顺序可以预测(在Java 7中,它可以是相当随机的)。

如果希望在JUnit 5中以特定顺序运行测试方法,可以使用下面的代码。

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MyClassTest { 

    @Test
    @Order(1)
    public void test1() {}

    @Test
    @Order(2)
    public void test2() {}

}

不确定我同意,如果我想测试“文件上传”,然后测试“文件上传插入的数据”,为什么我不希望这些是相互独立的?我认为能够分开运行它们是非常合理的,而不是在一个歌利亚测试案例中同时运行它们。

请看我的解决方案: “Junit和java 7。”

在本文中,我将描述如何按顺序运行junit测试——“就像在源代码中那样”。 测试将按照测试方法在类文件中出现的顺序运行。

http://intellijava.blogspot.com/2012/05/junit-and-java-7.html

但正如Pascal Thivent所说,这不是一个好的做法。

JUnit 5更新(以及我的观点)

我认为这对JUnit来说是非常重要的功能,如果JUnit的作者不想要订单功能,为什么?

默认情况下,单元测试库不会尝试按照源文件中出现的顺序执行测试。

JUnit 5和JUnit 4一样以这种方式工作。为什么?因为如果顺序很重要,这意味着一些测试在它们之间是耦合的,这对于单元测试来说是不可取的。 所以JUnit 5引入的@Nested特性遵循相同的默认方法。

But for integration tests, the order of the test method may matter since a test method may change the state of the application in a way expected by another test method. For example when you write an integration test for a e-shop checkout processing, the first test method to be executed is registering a client, the second is adding items in the basket and the last one is doing the checkout. If the test runner doesn't respect that order, the test scenario is flawed and will fail. So in JUnit 5 (from the 5.4 version) you have all the same the possibility to set the execution order by annotating the test class with @TestMethodOrder(OrderAnnotation.class) and by specifying the order with @Order(numericOrderValue) for the methods which the order matters.

例如:

@TestMethodOrder(OrderAnnotation.class) 
class FooTest {

    @Order(3)
    @Test
    void checkoutOrder() {
        System.out.println("checkoutOrder");
    }

    @Order(2)
    @Test
    void addItemsInBasket() {
        System.out.println("addItemsInBasket");
    }

    @Order(1)
    @Test
    void createUserAndLogin() {
        System.out.println("createUserAndLogin");
    }
}

输出:

创建用户和登录 添加物品在购物篮 结帐订单

顺便说一下,指定@TestMethodOrder(OrderAnnotation.class)看起来不需要(至少在我测试的5.4.0版本中是这样)。

边注 关于这个问题:JUnit 5是编写集成测试的最佳选择吗?我不认为它应该是首先考虑的工具(Cucumber和co可能经常为集成测试带来更具体的价值和特性),但在一些集成测试用例中,JUnit框架就足够了。所以这个功能的存在是个好消息。