我想以特定的顺序执行@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 4,将这个注释放在测试类上解决了这个问题。
@FixMethodOrder(MethodSorters.JVM)
其他回答
如果您摆脱了现有的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运行测试的方式是按字母名称升序排列。
所以只要按照你想要的字母顺序来命名你的测试。还要注意测试名称必须以开头 用单词测试。只是要注意数字
Test12将在test2之前运行
so:
testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond
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源代码
请看这个:https://github.com/TransparentMarket/junit。它按照指定的顺序(在已编译的类文件中定义)运行测试。此外,它还提供了一个AllTests套件,可以首先运行由子包定义的测试。使用AllTests实现还可以扩展过滤属性的解决方案(我们过去使用@Fast注释,但这些注释还没有发布)。
迁移到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注释更好,因为它为读者提供了更好的标记。