指定在方法级别(而不是类级别)联合 4 个测试的顺序
我知道这是不好的做法,但它需要完成,否则我需要切换到 testng
。有没有一种类似于 JUnit 3 的 testSuite 的方法来指定要在类中运行的测试的顺序?
I know this is bad practice, but it needs to be done, or I'll need to switch to testng
. Is there a way, similar to JUnit 3's testSuite, to specify the order of the tests to be run in a class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您确定您真的想要这样做:可能有更好的方法,但这就是我能想到的...
JUnit4 有一个注释:
@RunWith 可以让您覆盖测试的默认 Runner。
在您的情况下,您需要创建一个特殊的 BlockJunit4ClassRunner 子类,并重写computeTestMethods()以按照您希望执行的顺序返回测试。例如,假设我想按相反的字母顺序执行测试:
运行此测试会产生:
对于您的特定情况,您需要一个比较器,它可以按照您希望执行的顺序按名称对测试进行排序。 (我建议使用类似 Google Guava 的类
Ordering.explicit("methodName1","methodName2").onResultOf(...);
来定义比较器,其中 onResultOf 提供了一个将 FrameworkMethod 转换为它的名字......虽然显然你可以自由地以任何你想要的方式实现它。If you're sure you really want to do this: There may be a better way, but this is all I could come up with...
JUnit4 has an annotation:
@RunWith
which lets you override the default Runner for your tests.In your case you would want to create a special subclass of
BlockJunit4ClassRunner
, and overridecomputeTestMethods()
to return tests in the order you want them executed. For example, let's say I want to execute my tests in reverse alphabetical order:Running this test produces:
For your specific case, you would want a comparator that would sort the tests by name in the order you want them executed. (I would suggest defining the comparator using something like Google Guava's class
Ordering.explicit("methodName1","methodName2").onResultOf(...);
where onResultOf is provided a function that converts FrameworkMethod to its name... though obviously you are free to implement that any way you want.我可以看到这样做的几个原因,特别是在使用 JUnit 运行功能测试或测试持久对象时。例如,考虑一个持久存储到某种持久存储中的对象
Article
。如果我想按照单元测试原则“所有测试都应该可重新排序并仅测试功能的特定部分”来测试Article
对象上的插入、更新和删除功能,我将拥有三个测试:testInsertArticle()
testUpdateArticle()
testDeleteArticle()
但是,为了能够测试更新功能,我首先需要插入文章。为了测试删除功能,我还需要插入一篇文章。因此,实际上,插入功能已经在
testUpdateArticle()
和testDeleteArticle()
中进行了测试。然后,很容易创建一个测试方法testArticleFunctionality()
来完成这一切,但这样的方法最终会变得庞大(而且它们不会只测试的部分功能)文章
对象)。针对诸如 Restful API 之类的运行功能测试也是如此。如果不是测试的不确定顺序,JUnit 对于这些情况也非常有用。
也就是说,我扩展了 Michael D 的
OrderedRunner
以使用注释来确定测试顺序,只是认为我应该分享。它可以进一步扩展,例如通过准确指定每个测试所依赖的测试,但这就是我现在使用的。这是它的使用方式。它避免了命名测试的需要,例如
AA_testInsert()
、AB_testUpdate()
、AC_testDelete()
、...、ZC_testFilter( )
等。无论这些测试如何放置在文件中,它们始终都会以
order=1
首先、order=2
第二和最后运行order=3
,无论您是从 Eclipse 内部、使用 Ant 还是任何其他方式运行它们。实施如下。首先,注释
Order
。然后,修改
OrderedRunner
。I can see several reasons for doing this, especially when using JUnit to run functional tests or test persistent objects. For example, consider an object
Article
which is persisted to some kind of persistent storage. If I would like to test the insert, update and delete functionality on theArticle
object following the unit test principle "all tests should be reorderable and test only a specific part of the functionality", I would have three tests:testInsertArticle()
testUpdateArticle()
testDeleteArticle()
However, to be able to test the update functionality, I would first need to insert the article. To test the delete functionality, I would also need to insert an article. So, in practice, the insert functionality is already tested both in
testUpdateArticle()
andtestDeleteArticle()
. It is then tempting to just create a test methodtestArticleFunctionality()
which does it all, but methods like that will eventually get huge (and they won't just test part of the functionality of theArticle
object).The same goes for running functional tests against for example a restful API. JUnit is great also for these cases if it wasn't for the undeterministic ordering of tests.
That said, I extended Michael D's
OrderedRunner
to use annotations to determine order of tests, just thought I should share. It can be extended further, for example by specifying exactly which tests each test depends on, but this is what I'm using for now.This is how it is used. It avoids the need for naming tests like
AA_testInsert()
,AB_testUpdate()
,AC_testDelete()
, ...,ZC_testFilter()
, etc.No matter how these tests are placed in the file, they will always be run as
order=1
first,order=2
second and lastorder=3
, no matter if you run them from inside Eclipse, using Ant, or any other way.Implementation follows. First, the annotation
Order
.Then, the modified
OrderedRunner
.从 JUnit 版本 4.11 开始,可以通过使用
@FixMethodOrder
注释您的类并指定任何可用的MethodSorters
来影响测试执行的顺序。请参阅此链接了解更多详情。From JUnit version 4.11 onwards, it is possible to influence the order of test execution by annotating your class with
@FixMethodOrder
and specifying any of the availableMethodSorters
. See this link for more details.使用
junit 4.11
新注释@FixMethodOrder
允许设置特定顺序:Using
junit 4.11
the new annotation@FixMethodOrder
allows to set a specific order:如果您想按照“就像源代码中出现的那样”的顺序运行 junit 测试,
并且不想修改您的测试代码,
请参阅我关于此的注释:
如何按顺序运行 junit 测试它们出现在你的源代码中
但这确实不是一个好主意,测试必须是独立的。
If you want to run junit tests in order "just as they present in your source code",
and don't want to modify your tests code,
see my note about this here:
How to run junit tests in order as they present in your source code
But it is really not a good idea, tests must be independent.
Joscarsson 和 Michael D 在我的 github 存储库中编写代码。我希望他们不介意。我还为参数化类提供了有序版本。它已经用作 Maven 依赖项
Joscarsson and Michael D code in my github repo. I hope they don't mind. I also provide ordered version for Parameterized class. It's already to use as maven dependency