我想以特定的顺序执行@Test注释的测试方法。
例如:
public class MyTest {
@Test public void test1(){}
@Test public void test2(){}
}
我想确保每次运行MyTest时都在test2()之前运行test1(),但我找不到@Test(order=xx)这样的注释。
我认为这对JUnit来说是非常重要的功能,如果JUnit的作者不想要订单功能,为什么?
我想以特定的顺序执行@Test注释的测试方法。
例如:
public class MyTest {
@Test public void test1(){}
@Test public void test2(){}
}
我想确保每次运行MyTest时都在test2()之前运行test1(),但我找不到@Test(order=xx)这样的注释。
我认为这对JUnit来说是非常重要的功能,如果JUnit的作者不想要订单功能,为什么?
当前回答
不确定我同意,如果我想测试“文件上传”,然后测试“文件上传插入的数据”,为什么我不希望这些是相互独立的?我认为能够分开运行它们是非常合理的,而不是在一个歌利亚测试案例中同时运行它们。
其他回答
请看我的解决方案: “Junit和java 7。”
在本文中,我将描述如何按顺序运行junit测试——“就像在源代码中那样”。 测试将按照测试方法在类文件中出现的顺序运行。
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
但正如Pascal Thivent所说,这不是一个好的做法。
迁移到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注释更好,因为它为读者提供了更好的标记。
对于JUnit 4,将这个注释放在测试类上解决了这个问题。
@FixMethodOrder(MethodSorters.JVM)
正如其他人所说,理想情况下,测试应该独立于执行顺序。这使得测试不那么脆弱,并允许它们独立运行(许多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 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框架就足够了。所以这个功能的存在是个好消息。