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

例如:

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

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

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


当前回答

正如其他人所说,理想情况下,测试应该独立于执行顺序。这使得测试不那么脆弱,并允许它们独立运行(许多ide允许您选择一个测试方法并独立于其他测试执行它)。

话虽如此,对于集成测试,有些人更喜欢依赖于方法排序。

从JUnit 4.13开始,您可以通过扩展ordered定义自己的类来重新排序测试。请参阅JUnit wiki以获得更多详细信息。下面是一个示例,使用内置的Alphanumeric类使用测试方法名称按字母数字顺序对测试进行排序:

import org.junit.Test;
import org.junit.runner.OrderWith;
import org.junit.runner.manipulation.Alphanumeric;

@OrderWith(Alphanumeric.class)
public class TestMethodOrder {

    @Test
    public void testA() {
        System.out.println("first");
    }
    @Test
    public void testB() {
        System.out.println("second");
    }
    @Test
    public void testC() {
        System.out.println("third");
    }
}

其他回答

如果您摆脱了现有的Junit实例,并在构建路径中下载Junit 4.11或更高版本,以下代码将按照它们的名称(升序排序)执行测试方法:

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {

    @Test
    public void testAcreate() {
        System.out.println("first");
    }
    @Test
    public void testBupdate() {
        System.out.println("second");
    }
    @Test
    public void testCdelete() {
        System.out.println("third");
    }
}

下面是JUnit的一个扩展,可以生成所需的行为:https://github.com/aafuks/aaf-junit

我知道这与JUnit哲学的作者相违背,但是当在没有严格单元测试的环境中使用JUnit时(如在Java中实践的那样),这将非常有帮助。

JUnit从5.5开始允许在类上使用@TestMethodOrder(OrderAnnotation.class),在测试方法上使用@Order(1)。

JUnit旧版本允许测试方法使用类注释有序运行:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)

默认情况下,测试方法按字母顺序运行。所以,为了设置特定的方法,你可以像这样命名它们:

a_TestWorkUnit_WithCertainState_ShouldDoSomething b_TestWorkUnit_WithCertainState_ShouldDoSomething c_TestWorkUnit_WithCertainState_ShouldDoSomething

Or

_1_TestWorkUnit_WithCertainState_ShouldDoSomething _2_TestWorkUnit_WithCertainState_ShouldDoSomething _3_TestWorkUnit_WithCertainState_ShouldDoSomething

你可以在这里找到例子。

JUnit 4更新

从JUnit 4.13 @OrderWith开始,可以复制JUnit 5 @Order注释。这个解决方案与JUnit4的集成比@RunWith自定义BlockJUnit4ClassRunner实现更好。

下面是我如何用注释排序替换方法名排序(@FixMethodOrder(MethodSorters.NAME_ASCENDING))。

@OrderWith(OrderAnnotation.class)
public class MyTest {
    @Test
    @Order(-1)
    public void runBeforeNotAnnotatedTests() {}

    @Test
    public void notAnnotatedTestHasPriority0() {}

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

    @Test
    @Order(2)
    public void thisTestHasPriority2() {}
}
/**
 * JUnit 4 equivalent of JUnit 5's {@code org.junit.jupiter.api.Order}
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Order {
    /**
     * Default order value for elements not explicitly annotated with {@code @Order}.
     *
     * @see Order#value
     */
    int DEFAULT = 0;

    /**
     * The order value for the annotated element.
     * <p>Elements are ordered based on priority where a lower value has greater
     * priority than a higher value. For example, {@link Integer#MAX_VALUE} has
     * the lowest priority.
     *
     * @see #DEFAULT
     */
    int value();
}
import org.junit.runner.Description;
import org.junit.runner.manipulation.Ordering;
import org.junit.runner.manipulation.Sorter;

/**
 * Order test methods by their {@link Order} annotation. The lower value has the highest priority.
 * The tests that are not annotated get the default value {@link Order#DEFAULT}.
 */
public class OrderAnnotation extends Sorter implements Ordering.Factory {
    public OrderAnnotation() {
        super(COMPARATOR);
    }

    @Override
    public Ordering create(Context context) {
        return this;
    }

    private static final Comparator<Description> COMPARATOR = Comparator.comparingInt(
            description -> Optional.ofNullable(description.getAnnotation(Order.class))
                                   .map(Order::value)
                                   .orElse(Order.DEFAULT));
}

未加注释的测试的默认优先级为0。具有相同优先级的测试顺序尚未确定。

要点:https://gist.github.com/jcarsique/df98e0bad9e88e8258c4ab34dad3c863

启发:

Aman Goel的回答是 由JUnit团队编写的测试执行顺序 JUnit 5源代码

我最终认为我的测试没有按顺序运行,但事实是,混乱是在我的异步作业中。在使用并发性时,您还需要在测试之间执行并发性检查。 在我的例子中,作业和测试共享一个信号量,因此下一个测试挂起,直到正在运行的作业释放锁。

我知道这与这个问题并不完全相关,但也许可以帮助找到正确的问题