Java 如何在 JUnit4 中按特定顺序运行测试方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3693626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run test methods in specific order in JUnit4?
提问by u290629
I want to execute test methods which are annotated by @Test
in specific order.
我想执行按@Test
特定顺序注释的测试方法。
For example:
例如:
public class MyTest {
@Test public void test1(){}
@Test public void test2(){}
}
I want to ensure to run test1()
before test2()
each time I run MyTest
, but I couldn't find annotation like @Test(order=xx)
.
我想确保每次运行test1()
之前test2()
都运行MyTest
,但我找不到像@Test(order=xx)
.
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
我认为这是 JUnit 的一个非常重要的功能,如果 JUnit 的作者不想要订单功能,为什么?
采纳答案by Pascal Thivent
I think it's quite important feature for JUnit, if author of JUnit doesn't want the order feature, why?
我认为这是 JUnit 的一个非常重要的功能,如果 JUnit 的作者不想要订单功能,为什么?
I'm not sure there is a clean way to do this with JUnit, to my knowledge JUnit assumes that all tests can be performed in an arbitrary order. From the FAQ:
我不确定使用 JUnit 是否有一种干净的方法可以做到这一点,据我所知,JUnit 假设所有测试都可以按任意顺序执行。从常见问题解答:
How do I use a test fixture?
(...) The ordering of test-method invocations is not guaranteed, so testOneItemCollection() might be executed before testEmptyCollection(). (...)
如何使用测试夹具?
(...)不保证测试方法调用的顺序,因此 testOneItemCollection() 可能在 testEmptyCollection() 之前执行。(……)
Why is it so? Well, I believe that making tests order dependentis a practice that the authors don't want to promote. Tests should be independent, they shouldn't be coupled and violating this willmake things harder to maintain, will break the ability to run tests individually (obviously), etc.
为什么会这样?好吧,我相信让测试顺序依赖是作者不想提倡的做法。测试应该是独立的,他们不应该被耦合,并且违反本将让事情变得难以维持,将打破单独(明显),运行等测试的能力
That being said, if you really want to go in this direction, consider using TestNG since it supports running tests methods in any arbitrary order natively (and things like specifying that methods depends on groups of methods). Cedric Beust explains how to do this in order of execution of tests in testng.
话虽如此,如果您真的想朝这个方向发展,请考虑使用 TestNG,因为它支持以任意顺序本机运行测试方法(并且诸如指定方法之类的事情取决于方法组)。Cedric Beust 解释了如何按照 testng 中测试的执行顺序执行此操作。
回答by Xiè Jìléi
If the order is important, you should make the order yourself.
如果订单很重要,您应该自己下订单。
@Test public void test1() { ... }
@Test public void test2() { test1(); ... }
In particular, you should list some or all possible order permutations to test, if necessary.
特别是,如有必要,您应该列出一些或所有可能的顺序排列进行测试。
For example,
例如,
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(); }
Or, a full test of all permutations:
或者,对所有排列进行全面测试:
@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;
}
}
}
}
Here, permute()
is a simple function which iterates all possible permuations into a Collection of array.
这permute()
是一个简单的函数,它将所有可能的排列迭代到数组的集合中。
回答by Jesse Glick
The (as yet unreleased) change https://github.com/junit-team/junit/pull/386introduces a @SortMethodsWith
. https://github.com/junit-team/junit/pull/293at least made the order predictable without that (in Java 7 it can be quite random).
(尚未发布)更改https://github.com/junit-team/junit/pull/386引入了一个@SortMethodsWith
. https://github.com/junit-team/junit/pull/293至少可以在没有它的情况下预测顺序(在 Java 7 中它可以是非常随机的)。
回答by kornero
See my solution here: "Junit and java 7."
在此处查看我的解决方案:“Junit 和 java 7。”
In this article I describe how to run junit tests in order - "just as in your source code". Tests will be run, in order as your test methods appears in class file.
在本文中,我描述了如何按顺序运行 junit 测试 - “就像在您的源代码中一样”。将按照您的测试方法出现在类文件中的顺序运行测试。
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
But as Pascal Thivent said, this is not a good practise.
但正如 Pascal Thivent 所说,这不是一个好的做法。
回答by Anonymous Developer
Look at a JUnit report. JUnit is already organized by package. Each package has (or can have) TestSuite classes, each of which in turn run multiple TestCases. Each TestCase can have multiple test methods of the form public void test*()
, each of which will actually become an instance of the TestCase class to which they belong. Each test method (TestCase instance) has a name and a pass/fail criteria.
看一份 JUnit 报告。JUnit 已经按包组织。每个包都有(或可以有)TestSuite 类,每个类依次运行多个 TestCases。每个 TestCase 可以有多个形式为 的测试方法public void test*()
,每个方法实际上都会成为它们所属的 TestCase 类的一个实例。每个测试方法(TestCase 实例)都有一个名称和一个通过/失败标准。
What my management requires is the concept of individual TestStepitems, each of which reports their own pass/fail criteria. Failure of any test step must not prevent the execution of subsequent test steps.
我的管理层需要的是各个TestStep项目的概念,每个项目都报告自己的通过/失败标准。任何测试步骤的失败不得妨碍后续测试步骤的执行。
In the past, test developers in my position organized TestCase classes into packages that correspond to the part(s) of the product under test, created a TestCase class for each test, and made each test method a separate "step" in the test, complete with its own pass/fail criteria in the JUnit output. Each TestCase is a standalone "test", but the individual methods, or test "steps" within the TestCase, must occur in a specific order.
过去,我这个职位的测试开发人员将 TestCase 类组织成与被测产品的部分相对应的包,为每个测试创建一个 TestCase 类,并使每个测试方法成为测试中的一个单独的“步骤”,在 JUnit 输出中有自己的通过/失败标准。每个测试用例都是一个独立的“测试”,但是测试用例中的各个方法或测试“步骤”必须以特定的顺序出现。
The TestCase methods were the steps of the TestCase, and test designers got a separate pass/fail criterion per test step. Now the test steps are jumbled, and the tests (of course) fail.
TestCase 方法是 TestCase 的步骤,测试设计者在每个测试步骤都有一个单独的通过/失败标准。现在测试步骤混乱,测试(当然)失败。
For example:
例如:
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()
Each test method asserts and reports its own separate pass/fail criteria. Collapsing this into "one big test method" for the sake of ordering loses the pass/fail criteria granularity of each "step" in the JUnit summary report. ...and that upsets my managers. They are currently demanding another alternative.
每个测试方法都断言并报告自己单独的通过/失败标准。为了排序而将其折叠为“一个大的测试方法”会丢失 JUnit 摘要报告中每个“步骤”的通过/失败标准粒度。……这让我的经理很不高兴。他们目前正在要求另一种选择。
Can anyone explain how a JUnit with scrambled test method ordering would support separate pass/fail criteria of each sequential test step, as exemplified above and required by my management?
任何人都可以解释带有乱序测试方法排序的 JUnit 如何支持每个顺序测试步骤的单独通过/失败标准,如上面举例说明和我的管理层所要求的那样?
Regardless of the documentation, I see this as a serious regression in the JUnit framework that is making life difficult for lots of test developers.
无论文档如何,我都认为这是 JUnit 框架中的一个严重回归,它使许多测试开发人员的日子变得艰难。
回答by pstorli
I've read a few answers and agree its not best practice, but the easiest way to order your tests - and the way that JUnit runs tests by default is by alphabetic name ascending.
我已经阅读了一些答案并同意它不是最佳实践,而是排序测试的最简单方法 - 并且 JUnit 默认运行测试的方式是按字母名称升序。
So just name your tests in the alphabetic order that you want. Also note the test name must begin with the word test. Just watch out for numbers
因此,只需按您想要的字母顺序命名您的测试。另请注意,测试名称必须以单词 test 开头。只看数字
test12 will run before test2
test12 将在 test2 之前运行
so:
所以:
testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond
testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond
回答by joro
Migration to TestNG seems the best way, but I see no clear solution here for jUnit. Here is most readable solution / formattingI found for jUnit:
迁移到 TestNG 似乎是最好的方法,但我在这里看不到 jUnit 的明确解决方案。这是我为 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(){}
}
This ensures stage2 methods are called after stage1 ones and before stage3 ones.
这确保在 stage1 之后和 stage3 之前调用 stage2 方法。
回答by Aniket Kulkarni
If you get rid of your existing instance of Junit, and download JUnit 4.11or greater in the build path, the following code will execute the test methods in the order of their names, sorted in ascending order:
如果删除现有的 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");
}
}
回答by CharlieS
What you want is perfectly reasonable when test cases are being run as a suite.
当测试用例作为套件运行时,您想要的是完全合理的。
Unfortunately no time to give a complete solution right now, but have a look at class:
不幸的是现在没有时间给出一个完整的解决方案,但看看类:
org.junit.runners.Suite
Which allows you to call test cases (from any test class) in a specific order.
这允许您以特定顺序调用测试用例(来自任何测试类)。
These might be used to create functional, integration or system tests.
这些可用于创建功能、集成或系统测试。
This leaves your unit tests as they are without specific order (as recommended), whether you run them like that or not, and then re-use the tests as part of a bigger picture.
这使您的单元测试没有特定的顺序(按照建议),无论您是否这样运行它们,然后重新使用测试作为更大图景的一部分。
We re-use/inherit the same code for unit, integration and system tests, sometimes data driven, sometimes commit driven, and sometimes run as a suite.
我们为单元、集成和系统测试重用/继承相同的代码,有时是数据驱动的,有时是提交驱动的,有时是作为套件运行的。
回答by Mattk
Not sure I agree, If I want to test 'File Upload' and then test 'Data Inserted by File Upload' why would I not want these to be independent from each other? Perfectly reasonable I think to be able to run them separately rather than having both in a Goliath test case.
不确定我同意,如果我想测试“文件上传”,然后测试“文件上传插入的数据”,为什么我不希望它们彼此独立?我认为能够单独运行它们而不是在 Goliath 测试用例中同时运行它们是完全合理的。