在方法级别指定一个命令来联合4个testing(不是类级别)

我知道这是不好的做法,但需要做,否则我需要切换到testng 。 有没有类似于JUnit 3的testSuite的方法来指定要在类中运行的testing的顺序?

如果你确定你真的想这样做:可能有更好的办法,但这是我能想出来的…

JUnit4有一个注释: @RunWith ,它可以让你覆盖testing的默认Runner。

在你的情况下,你会想创build一个BlockJunit4ClassRunner的特殊子类,并重写computeTestMethods()来按照你希望它们执行的顺序返回testing。 例如,假设我想按字母顺序执行我的testing:

 public class OrderedRunner extends BlockJUnit4ClassRunner { public OrderedRunner(Class klass) throws InitializationError { super(klass); } @Override protected List computeTestMethods() { List list = super.computeTestMethods(); List copy = new ArrayList(list); Collections.sort(copy, new Comparator() { public int compare(FrameworkMethod o1, FrameworkMethod o2) { return o2.getName().compareTo(o1.getName()); } }); return copy; } } 
 @RunWith(OrderedRunner.class) public class OrderOfTest { @Test public void testA() { System.out.println("A"); } @Test public void testC() { System.out.println("C"); } @Test public void testB() { System.out.println("B"); } } 

运行这个testing会产生:

  C
乙
一个 

对于您的具体情况,您需要一个比较器,按您希望执行的顺序按名称对testing进行sorting。 (我会build议使用类似Google Guava类Ordering.explicit("methodName1","methodName2").onResultOf(...);来定义比较器Ordering.explicit("methodName1","methodName2").onResultOf(...);其中onResultOf提供了一个将FrameworkMethod转换为其名称的函数…你可以自由地实现你想要的任何方式。

我可以看到几个这样做的原因,尤其是当使用JUnit来运行functiontesting或testing持久对象时。 例如,考虑一个坚持某种持久性存储的对象Article 。 如果我想按照unit testing原则testing插入,更新和删除Article对象的function,“所有的testing都应该是可重新订购的,并且只testing一个特定的function部分”,我会有三个testing:

  • testInsertArticle()
  • testUpdateArticle()
  • testDeleteArticle()

但是,为了能够testing更新function,我首先需要插入文章。 为了testing删除function,我还需要插入一篇文章。 所以,在实践中,插入function已经在testUpdateArticle()testDeleteArticle()进行了testing。 然后创build一个testing方法testArticleFunctionality()就可以了,但是像这样的方法最终会变得非常庞大(而且它们不会仅仅testingArticle对象的一部分function)。

运行functiontesting例如对于一个restful API也是如此。 如果不是testing的不确定性sorting,JUnit对于这些情况也是很好的。

也就是说,我扩展了Michael D' OrderedRunner来使用注释来确定testing顺序,只是认为我应该分享。 它可以进一步扩展,例如通过指定每个testing依赖哪个testing,但这是我现在使用的。

这是如何使用它。 它避免了像AA_testInsert()AB_testUpdate()AC_testDelete() ,…, ZC_testFilter()等命名testing的需要。

 @RunWith(OrderedRunner.class) public class SomethingTest { @Test @Order(order=2) public void testUpdateArticle() { // test update } @Test @Order(order=1) public void testInsertArticle() { // test insert } @Test @Order(order=3) public void testDeleteArticle() { // test delete } } 

无论这些testing如何放置在文件中,无论您是从Eclipse内部,使用Ant还是其他任何方式运行它们,它们都将始终按order=1order=2秒和order=3运行。

执行如下。 首先是注释Order

 @Retention(RetentionPolicy.RUNTIME) public @interface Order { public int order(); } 

然后,修改OrderedRunner

 public class OrderedRunner extends BlockJUnit4ClassRunner { public OrderedRunner(Class<?> klass) throws InitializationError { super(klass); } @Override protected List<FrameworkMethod> computeTestMethods() { List<FrameworkMethod> list = super.computeTestMethods(); Collections.sort(list, 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 list; } } 

从JUnit版本4.11开始,可以通过@FixMethodOrder注释你的类并指定任何可用的MethodSorters来影响testing执行的顺序。 看到这个链接了解更多细节。

使用junit 4.11 新的注解 @FixMethodOrder允许设置特定的顺序:

 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 

如果你想按照“就像它们出现在你的源代码中”一样运行junittesting,并且不想修改你的testing代码,请参阅我的注释:

如何在源代码中运行junittesting

但这真的不是一个好主意,testing必须是独立的。

Joscarsson和迈克尔D代码在我的github回购。 我希望他们不介意。 我还提供了参数化类的有序版本。 它已经被用作maven依赖

 <repositories> <repository> <id>git-xxx</id> <url>https://github.com/crsici/OrderedRunnerJunit4.11/raw/master/</url> </repository> </repositories> <dependency> <groupId>com.sici.org.junit</groupId> <artifactId>ordered-runner</artifactId> <version>0.0.1-RELEASE</version> </dependency>