我想以特定的顺序执行@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的作者不想要订单功能,为什么?
当前回答
是时候转向Junit5了。 以下是我们可以得到的一个例子:
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderedTests {
@Test
@Order(1)
void nullValues() {}
@Test
@Order(2)
void emptyValues() {}
@Test
@Order(3)
void validValues() {}
}
对于Junit4,将多个测试中的逻辑复制到一个测试方法中。
其他回答
这是我在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()”的方法开始。 谢谢!
你可以使用这些代码中的一段: @FixMethodOrder(MethodSorters.JVM)或@FixMethodOrder(MethodSorters.DEFAULT)或@FixMethodOrder(MethodSorters.NAME_ASCENDING)
在你的测试类之前,像这样:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest {...}
我认为这对JUnit来说是非常重要的功能,如果JUnit的作者不想要订单功能,为什么?
我不确定是否有一种干净的方法可以用JUnit做到这一点,据我所知,JUnit假设所有测试都可以以任意顺序执行。常见问题解答:
如何使用测试夹具? (…)不能保证测试方法调用的顺序,因此testOneItemCollection()可能会在testEmptyCollection()之前执行。(…)
为什么会这样?好吧,我相信让测试依赖于顺序是作者不想提倡的做法。测试应该是独立的,它们不应该是耦合的,违反这一点会让事情更难维护,会破坏单独运行测试的能力(显然)等等。
话虽如此,如果您真的想朝着这个方向发展,可以考虑使用TestNG,因为它支持以任意顺序本机运行测试方法(以及诸如指定方法依赖于方法组之类的事情)。Cedric Beust解释了如何按照测试中执行测试的顺序来做这件事。
我最终认为我的测试没有按顺序运行,但事实是,混乱是在我的异步作业中。在使用并发性时,您还需要在测试之间执行并发性检查。 在我的例子中,作业和测试共享一个信号量,因此下一个测试挂起,直到正在运行的作业释放锁。
我知道这与这个问题并不完全相关,但也许可以帮助找到正确的问题
如果您摆脱了现有的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");
}
}