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

例如:

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

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

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


当前回答

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

其他回答

看一看JUnit报告。JUnit已经按包组织。每个包都有(或可以有)TestSuite类,每个类依次运行多个testcase。每个TestCase可以有多个public void test*()形式的测试方法,每个测试方法实际上都将成为它们所属的TestCase类的实例。每个测试方法(TestCase实例)都有一个名称和一个通过/失败的标准。

我的管理需要的是单独的TestStep项的概念,每个项报告自己的通过/失败标准。任何测试步骤的失败都不能阻止后续测试步骤的执行。

在过去,在我的位置上,测试开发人员将TestCase类组织到与所测试产品的部分相对应的包中,为每个测试创建一个TestCase类,并使每个测试方法成为测试中的单独“步骤”,在JUnit输出中完成它自己的通过/失败标准。每个TestCase都是一个独立的“测试”,但是TestCase中的各个方法,或者测试“步骤”,必须以特定的顺序发生。

TestCase方法是TestCase的步骤,并且测试设计者得到了每个测试步骤单独的通过/失败标准。现在测试步骤变得混乱,测试(当然)失败了。

例如:

Class testStateChanges extends TestCase

public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()

每个测试方法都断言并报告自己独立的通过/失败标准。 为了排序,将其分解为“一个大的测试方法”会丢失JUnit摘要报告. ...中每个“步骤”的通过/失败标准粒度这让我的经理们很不高兴。他们目前要求另一种选择。

谁能解释一下,一个具有打乱测试方法排序的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从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,将这个注释放在测试类上解决了这个问题。

@FixMethodOrder(MethodSorters.JVM)