【问题标题】:Running all tests from a @Category using Maven使用 Maven 从 @Category 运行所有测试
【发布时间】:2011-06-25 14:33:27
【问题描述】:

我只想运行我的单元测试的一个子集,这些单元测试由特定的@Category 定义。

所以我阅读了几个 SO 问题,例如 this one(这正是我要找的),还有 this one。

我的问题的解决方案似乎是由ClasspathSuite project 提供的。所以我开始编写NewTest 和OldTest 接口来定义我的测试类别。然后,我创建了AllTests 套件:

@RunWith(ClasspathSuite.class)
public class AllTests { }

之后,我创建了一个AllNewTests 套件:

@RunWith(Categories.class)
@IncludeCategory(NewTest.class)
@SuiteClasses( { AllTests.class })
public class AllNewTests { }

最后,我创建了两个 JUnit 类,每个类别一个:

@Category(NewTest.class)
public class SomeNewTests {
    // some tests...
}

@Category(OldTest.class)
public class SomeOldTests {
    // some tests...
}

现在,如果我运行 AllTests,Eclipse 会启动我项目的所有测试,而 Maven 会因为找不到测试而失败:

mvn test -Dtest=AllTests

...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running my.company.AllTests
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.093 sec
There are no tests to run.

如果我运行 AllNewTests(这是正确的做法,对吗?),在 Eclipse 中一切都很好(即它只运行带有 @Category(NewTest.class) 注释的测试)但是 Maven返回错误:

mvn test -Dtest=AllNewTests

...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running my.company.AllNewTests
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.125 sec <<< FAILURE!

Results :

Tests in error:
  initializationError(my.company.AllNewTests)

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

抛出的异常如下:

org.junit.runner.manipulation.NoTestsRemainException
    at org.junit.runners.ParentRunner.filter(ParentRunner.java:256)
    at org.junit.experimental.categories.Categories.<init>(Categories.java:142)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:35)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:33)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    at $Proxy0.invoke(Unknown Source)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:70)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

我的问题是我做错了什么?


技术细节:Java 6、Maven 3.0.2、JUnit 4.8.1、Surefire 插件 2.7.1、cpsuite-1.2.5

【问题讨论】:

    标签: junit maven categories surefire


    【解决方案1】:

    作为更新:从 Surefire 插件 v2.11 开始,现在支持 JUnit 4.8+ 样式类别。

    release notes for Surefire v2.11 提到了新功能。可以使用 groups 配置 surefire:test 目标。

    【讨论】:

    • 你真的成功了吗?我似乎无法让它工作。 Surefire (2.11 / 2.12) 似乎忽略了这些组。它只是运行所有测试。
    • @JanGoyvaerts 这是一个错误,现已修复。事实上,要运行 2.11 和 2.12 中的类别,您必须指定对 junit 47 提供程序 (surefire-junit47) 的依赖。这是在 2.13-SNAPSHOT 中修复的,并且应该在没有显式依赖的情况下工作。
    • 我已经按照你说的完成了它。但是......提供者存在很大的性能问题。它缓冲日志(这还不错)并在测试持续时间过长时吃掉所有内存和 CPU。所以我改用了命名约定——因为它本来就是这样。这没有问题。我已经指出了问题。
    【解决方案2】:

    我通过创建自己的JUnit Runner 解决了我的问题,它扩展了Suite。

    这个想法接近Classpath Suite项目的原理,即寻找存在于类路径中的类,只保留那些被给定注解的类(例如@NewTest)。

    有兴趣的可以阅读full story on my blog。

    【讨论】:

    • 这个方法现在已经完全过时了,随着surefire插件的发展(见user1034382答案)。
    【解决方案3】:

    在阅读了一些博客文章和 stackoverflow 问题后,我终于能够使用 surefire 插件来完成这项工作,正如 user1034382 所回答的那样。就我而言,使用 maven-surefire-plugin 的 2.17 版。

    只是为了添加我的两分钱,可以在这里找到更多最新的解释: Using JUnit Categories to group tests

    但您可能会遇到以下万无一失的插件问题:

    [ERROR] java.lang.RuntimeException: Unable to load category:
    

    这可以通过其他 stackoverflow 问题/答案来解决: Where should I put interface class for Junit @Category?

    我的回答只是在这里收集所有这些信息,避免使用谷歌搜索/阅读许多不同的解决方案。至少,这对我有用。

    【讨论】:

      猜你喜欢
      • 2012-01-15
      • 2016-03-13
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多