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

例如:

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

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

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


当前回答

这是我在Junit工作时遇到的主要问题之一,我想出了以下解决方案,对我来说很好:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;

public class OrderedRunner extends BlockJUnit4ClassRunner {

    public OrderedRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
        Collections.sort(copy, new Comparator<FrameworkMethod>() {

            @Override
            public int compare(FrameworkMethod f1, FrameworkMethod f2) {
                Order o1 = f1.getAnnotation(Order.class);
                Order o2 = f2.getAnnotation(Order.class);

                if (o1 == null || o2 == null) {
                    return -1;
                }

                return o1.order() - o2.order();
            }
        });
        return copy;
    }
}

还可以创建如下界面:

 @Retention(RetentionPolicy.RUNTIME)


@Target({ ElementType.METHOD})

public @interface Order {
public int order();
}

现在假设你有一个类A,你写了几个测试用例,如下所示:

(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)

void method(){

//do something

}

}

因此,执行将从名为“method()”的方法开始。 谢谢!

其他回答

是时候转向Junit5了。 以下是我们可以得到的一个例子:

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

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

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

     @Test
     @Order(3)
     void validValues() {}
 }

对于Junit4,将多个测试中的逻辑复制到一个测试方法中。

使用JUnit 5.4,你可以指定顺序:

@Test
@Order(2)
public void sendEmailTestGmail() throws MessagingException {

你只需要注释你的类

@TestMethodOrder(OrderAnnotation.class)

https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-execution-order

我在我的项目中使用这个,它工作得非常好!

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

我不确定是否有一种干净的方法可以用JUnit做到这一点,据我所知,JUnit假设所有测试都可以以任意顺序执行。常见问题解答:

如何使用测试夹具? (…)不能保证测试方法调用的顺序,因此testOneItemCollection()可能会在testEmptyCollection()之前执行。(…)

为什么会这样?好吧,我相信让测试依赖于顺序是作者不想提倡的做法。测试应该是独立的,它们不应该是耦合的,违反这一点会让事情更难维护,会破坏单独运行测试的能力(显然)等等。

话虽如此,如果您真的想朝着这个方向发展,可以考虑使用TestNG,因为它支持以任意顺序本机运行测试方法(以及诸如指定方法依赖于方法组之类的事情)。Cedric Beust解释了如何按照测试中执行测试的顺序来做这件事。

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

我已经阅读了一些答案,并同意这不是最佳实践,但最简单的方法是对测试进行排序——默认情况下,JUnit运行测试的方式是按字母名称升序排列。

所以只要按照你想要的字母顺序来命名你的测试。还要注意测试名称必须以开头 用单词测试。只是要注意数字

Test12将在test2之前运行

so:

testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond