我想执行由@Test
按特定顺序注释的测试方法。
例如:
public class MyTest {
@Test public void test1(){}
@Test public void test2(){}
}
我想确保每次运行test1()
时都在test2()
之前运行MyTest
,但我找不到像@Test(order=xx)
这样的注释。
我认为这对JUnit来说非常重要,如果JUnit的作者不想要订单功能,为什么?
我认为这对JUnit来说非常重要,如果JUnit的作者不想要订单功能,为什么?
我不确定JUnit是否有一种干净的方法,据我所知,JUnit假定所有测试都可以按任意顺序执行。来自FAQ:
How do I use a test fixture?
(...)不保证测试方法调用的顺序,因此testOneItemCollection()可能在testEmptyCollection()之前执行。 (......)
为什么会这样?好吧,我相信让测试顺序依赖是作者不想推广的做法。测试应该是独立的,它们不应该是耦合的,违反它会使事情变得更难维护,会破坏单独运行测试的能力(显然)等等。
话虽这么说,如果你真的想要朝着这个方向前进,可以考虑使用TestNG,因为它支持以任意顺序本地运行测试方法(而且指定方法取决于方法组)。 Cedric Beust在order of execution of tests in testng解释了如何做到这一点。
不确定我同意,如果我想测试'文件上传'然后测试'文件上传插入的数据',为什么我不希望它们彼此独立?非常合理我认为能够单独运行它们而不是同时使用Goliath测试用例。
在这里查看我的解决方案:“Junit和java 7.”
在本文中,我将介绍如何按顺序运行junit测试 - “就像在源代码中一样”。将按照测试方法出现在类文件中的顺序运行测试。
org.junit.runners.Suite
但正如Pascal Thivent所说,这不是一个好习惯。
我已经阅读了一些答案并同意它不是最佳实践,但是最简单的订购测试方法 - 以及JUnit默认运行测试的方式是按字母名称升序。
因此,只需按照您想要的字母顺序命名测试。另请注意,测试名称必须以单词test开头。请注意数字
test12将在test2之前运行
所以:
testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond
请看看这个:http://intellijava.blogspot.com/2012/05/junit-and-java-7.html。它按照指定的顺序运行测试(在已编译的类文件中定义)。它还具有一个AllTests套件,可以首先运行子包定义的测试。使用AllTests实现,可以扩展解决方案,同时过滤属性(我们曾经使用过@Fast注释,但那些尚未发布)。
这是JUnit的扩展,可以产生所需的行为:https://github.com/TransparentMarket/junit
我知道这是针对JUnit哲学的作者,但是当在非严格的单元测试(在Java中实践)的环境中使用JUnit时,这可能非常有用。
我最后在这里认为我的测试没有按顺序运行,但事实是,混乱是在我的异步工作中。使用并发时,您还需要在测试之间执行并发检查。在我的例子中,作业和测试共享一个信号量,因此下一个测试会挂起,直到正在运行的作业释放锁定。
我知道这与这个问题并不完全相关,但可能有助于针对正确的问题
你可以使用以下代码之一:
https://github.com/aafuks/aaf-junit
使用JUnit 5.4,您可以指定顺序:
@FixMethodOrder(MethodSorters.JVM)OR `@FixMethodOrder(MethodSorters.DEFAULT)` OR `@FixMethodOrder(MethodSorters.NAME_ASCENDING)` before your test class like this:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest { ...}
你只需要注释你的课程
@Test
@Order(2)
public void sendEmailTestGmail() throws MessagingException {
@TestMethodOrder(OrderAnnotation.class)
我在我的项目中使用它,它工作得很好!
如果您删除现有的Junit实例,并在构建路径中下载JUnit 4.11或更高版本,则以下代码将按其名称的顺序执行测试方法,并按升序排序:
@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");
}
}
如果订单很重要,您应该自己下订单。
@Test public void test1() { ... }
@Test public void test2() { test1(); ... }
特别是,如有必要,您应列出一些或所有可能的订单排列以进行测试。
例如,
void test1();
void test2();
void test3();
@Test
public void testOrder1() { test1(); test3(); }
@Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }
@Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }
或者,对所有排列进行全面测试:
@Test
public void testAllOrders() {
for (Object[] sample: permute(1, 2, 3)) {
for (Object index: sample) {
switch (((Integer) index).intValue()) {
case 1: test1(); break;
case 2: test2(); break;
case 3: test3(); break;
}
}
}
}
在这里,qazxsw poi是一个简单的函数,它将所有可能的排列迭代到一个数组集合中。
迁移到TestNG似乎是最好的方法,但我看不到jUnit的明确解决方案。这是我为jUnit找到的最易读的解决方案/格式:
permute()
这确保了在阶段1之后和阶段3之前调用阶段2方法。
这是我在Junit工作时遇到的主要问题之一,我提出了以下解决方案,对我来说很好:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
@Test
void stage1_prepareAndTest(){};
@Test
void stage2_checkSomething(){};
@Test
void stage2_checkSomethingElse(){};
@Test
void stage3_thisDependsOnStage2(){};
@Test
void callTimeDoesntMatter(){}
}
还创建如下界面:
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;
}
}
现在假设您有A类,您已经编写了几个测试用例,如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface Order {
public int order();
}
因此,执行将从名为“method()”的方法开始。谢谢!
(尚未发布)改变(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)
void method(){
//do something
}
}
引入了https://github.com/junit-team/junit/pull/386。 @SortMethodsWith
至少在没有它的情况下使订单可预测(在Java 7中它可以是非常随机的)。
查看JUnit报告。 JUnit已经按包组织。每个包都有(或可以有)TestSuite类,每个类依次运行多个TestCase。每个TestCase都可以有多个https://github.com/junit-team/junit/pull/293形式的测试方法,每个测试方法实际上都会成为它们所属的TestCase类的一个实例。每个测试方法(TestCase实例)都有一个名称和通过/失败标准。
我的管理层需要的是各个TestStep项目的概念,每个项目都报告自己的通过/未通过标准。任何测试步骤的失败都不得妨碍后续测试步骤的执行。
过去,我职位的测试开发人员将TestCase类组织成与被测产品的部件相对应的包,为每个测试创建一个TestCase类,并使每个测试方法成为测试中的单独“步骤”,在JUnit输出中完成自己的通过/失败标准。每个TestCase都是独立的“测试”,但TestCase中的各个方法或测试“步骤”必须按特定顺序进行。
TestCase方法是TestCase的步骤,测试设计者在每个测试步骤中获得单独的通过/失败标准。现在测试步骤混乱,测试(当然)失败。
例如:
public void test*()
每种测试方法都断言并报告其自己的单独通过/未通过标准。为了订购,将其折叠为“一个大的测试方法”会丢失JUnit摘要报告中每个“步骤”的通过/失败标准粒度。 ......这让我的经理感到不安。他们目前要求另一种选择。
任何人都可以解释一个带有加扰测试方法排序的JUnit如何支持每个顺序测试步骤的单独通过/失败标准,如上面举例说明并且我的管理人员要求?
无论文档如何,我都认为这是JUnit框架中的一个严重的回归,它使许多测试开发人员的生活变得困难。
JUnit目前允许测试方法使用类注释运行排序:
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()
默认情况下,测试方法按字母顺序运行。因此,要设置特定的方法顺序,您可以将它们命名为:
a_TestWorkUnit_WithCertainState_ShouldDoSomething b_TestWorkUnit_WithCertainState_ShouldDoSomething c_TestWorkUnit_WithCertainState_ShouldDoSomething
你可以找到@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)
。
当测试用例作为套件运行时,您想要的是完全合理的。
不幸的是现在没有时间提供完整的解决方案,但看看课程:
examples here
这允许您按特定顺序调用测试用例(来自任何测试类)。
这些可能用于创建功能,集成或系统测试。
这使得您的单元测试没有特定的顺序(按照建议),无论您是否运行它们,然后重新使用测试作为更大图片的一部分。
我们为单元,集成和系统测试重用/继承相同的代码,有时是数据驱动的,有时是提交驱动的,有时是作为套件运行的。