Java Maven找不到要运行的JUnit测试

Java Maven找不到要运行的JUnit测试,java,maven,junit,Java,Maven,Junit,我有一个maven程序,它编译得很好。当我运行mvn测试时,它不会运行“测试”标题下的任何测试,该标题表示没有要运行的测试 我用一个超级简单的设置重新创建了这个问题,我将在下面介绍这个设置以及使用-X运行时的输出 单元测试在eclipse中运行良好,既有默认的junit包,也有maven下载的junit.jar。此外,mvn测试编译正确地创建测试类下的类。我在OSX 10.6.7上运行它,使用Maven 3.0.2和java 1.6.0_24 以下是目录结构: /my_program/pom.x

我有一个maven程序,它编译得很好。当我运行mvn测试时,它不会运行“测试”标题下的任何测试,该标题表示没有要运行的测试

我用一个超级简单的设置重新创建了这个问题,我将在下面介绍这个设置以及使用-X运行时的输出

单元测试在eclipse中运行良好,既有默认的junit包,也有maven下载的junit.jar。此外,mvn测试编译正确地创建测试类下的类。我在OSX 10.6.7上运行它,使用Maven 3.0.2和java 1.6.0_24

以下是目录结构:

/my_program/pom.xml
/my_program/src/main/java/ClassUnderTest.java
/my_program/src/test/java/ClassUnderTestTests.java
pom.xml:

ClassUnderTestTests.java:

mvn-X测试结束:

默认情况下,在查找要运行的测试时,Maven:

试验* *试验 *测验 *测试用例
如果您的测试类不遵循这些约定,您应该重命名它或为测试类使用另一种模式。

我还发现单元测试代码应该放在src/test/java文件夹下,如果您将其放在主文件夹下,则无法将其识别为测试类。 例如


如果您有一个共享的Java/Groovy应用程序,并且只有Groovy单元测试,那么Maven将找不到任何测试。这可以通过在src/test/java下添加一个单元测试来解决。

此外,检查您的测试类目录(例如src/test/java)是否对应于property下pom.xml的property中列出的目录。我花了一段时间才找到它。

检查jUnit-4.12和EclipseSureFire插件

在依赖项中的POM.xml中添加所需的jUnit版本。执行Maven->updateproject以查看在project中导出的所需jar。 Test类位于src/Test/java文件夹下,可以在config testSourceDirectory的POM中指定此文件夹或基本文件夹的子目录。类的名称应该有尾词“Test”。 测试类中的测试方法应具有注释@Test
如果模块的封装声明不正确,另一件事可能会导致Maven找不到测试


在最近的一个案例中,有人患有pom,而我的测试从未运行过。我将它改为jar,现在它工作正常。

发现如果在测试前加上“Abstract”,默认情况下它也将被忽略。

如果项目有pom,Maven将不会运行测试

如果使用的JUnit不是标准的JUnit:JUnit,那么需要将打包设置为jar或其他java人工制品类型,以便运行测试:jar

<dependency>
    <groupId>org.eclipse.orbit</groupId>
    <artifactId>org.junit</artifactId>
    <version>4.11.0</version>
    <type>bundle</type>
    <scope>test</scope>
</dependency>

我也有类似的问题,在探索后发现testng依赖性导致了这个问题。在从pom中删除testng依赖项(因为我不再需要它)之后,它开始对我起作用

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.8</version>
        <scope>test</scope>
    </dependency>

不运行测试用例的另一个原因发生在我身上——我有一个名为test的属性,用于完全不同的目的,但它干扰了surefire插件。因此,请检查您的POM:

<properties>
  <test>.... </test>
  ...
</properties>
并将其移除

/my_program/src/test/java/ClassUnderTestTests.java
应该是

/my_program/src/test/java/ClassUnderTestTest.java
Maven会自动找到那些以测试结束或以测试开始的测试

但是,您可以使用

mvn surefire:test -Dtest=ClassUnderTestTests.java 

运行您的测试。

如果有人搜索了,而我没有解决它,我有一个用于不同测试的库:

<dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${org.junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>
当我安装junit时,一切正常,我希望并帮助您:

<dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
更新:

正如@scottyseus在评论中所说,从Maven Surefire 2.22.0开始,以下内容就足够了:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.1</version>
</plugin>
资料来源:

更新2021

最初由junit团队开发的junit平台surefire提供程序在junit平台1.3中被弃用,并在1.4中停止使用。请改用Maven Surefire的本机支持


如果您的测试类名没有遵循上面@axtavt突出显示的标准命名约定,则需要在pom.xml中添加模式/类名,以便选择测试-

... org.apache.maven.plugins maven surefire插件 **/*_UT.java ...
除了前面的答案之外,还有一个提示:

在Eclipse中,转到项目的属性>单击运行/调试设置:

此页面允许您使用管理启动配置 当前选定的资源


在那里你可以添加新的。。。或者删除项目中src/test/java文件夹或课程下的JU JUnit测试。

以下是我必须添加到pom.xml中的确切代码:

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.2.0-M1</version>
                </dependency>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.2.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
以下是我的依赖项:

    <dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.2.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easytesting</groupId>
        <artifactId>fest-assert-core</artifactId>
        <version>2.0M10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-surefire-provider</artifactId>
        <version>1.2.0-M1</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.2.0-M1</version>
    </dependency>
</dependencies>

如果您已经在JUnit4中编写了测试,并向surefire插件添加了JUnit5依赖项,那么您的测试将不会运行

在这种情况下,只需从surefire插件中注释JUnit 5依赖项:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <!--<dependencies>-->
                <!--<dependency>-->
                    <!--<groupId>org.junit.platform</groupId>-->
                    <!--<artifactId>junit-platform-surefire-provider</artifactId>-->
                    <!--<version>1.0.0</version>-->
                <!--</dependency>-->
                <!--<dependency>-->
                    <!--<groupId>org.junit.jupiter</groupId>-->
                    <!--<artifactId>junit-jupiter-engine</artifactId>-->
                    <!--<version>${junit.version}</version>-->
                <!--</dependency>-->
            <!--</dependencies>-->
        </plugin>

在我的例子中,它添加了JUnitVintage引擎,这使它与旧版本的junit测试兼容,并且可以运行它们。因为我正在使用JUnit5

<dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <scope>test</scope>
</dependency>

我也遇到了同样的问题,通过以下pom.xml中的更改解决了这个问题:

<build>
    <testSourceDirectory>test</testSourceDirectory>

改为:

<build>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>

这些答案中有许多在过去对我非常有用,但我想补充一个花费了我一些时间的额外场景,因为它可能在未来帮助其他人:

确保测试类和方法是公共的


我的问题是,我在使用IDEIntelliJ的自动测试类/方法生成功能,出于某种原因,它将它们创建为包私有。我发现这比人们预期的更容易出错。

当您将冲浪插件3.x.x+与JUnit5一起使用时,可能会出现这种问题,并且错误地使用JUnit4中的@test annotation对测试类进行注释

使用:org.junit.jupiter.api.Test JUnit5而不是org.junit.Test Junit4


注意:这可能很难注意到,因为IDE可能会像JUnit4测试一样在没有问题的情况下运行此测试。

以下内容对我来说在JUnit5中很好


我最近遇到的另一个容易被忽视的问题是,确保测试类的文件具有.java扩展名。如果没有要编译的测试,就没有要运行的测试。在我的例子中,我们正在将多模块应用程序迁移到Spring Boot。不幸的是,maven不再执行模块中的所有测试。测试类的命名没有改变,我们遵循命名约定

最后,当我将依赖项surefire-junit47添加到插件maven surefire插件时,它起到了帮助作用。但我无法解释,为什么,这是反复试验:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
  <dependency>
    <groupId>org.apache.maven.surefire</groupId>
    <artifactId>surefire-junit47</artifactId>
    <version>${maven-surefire-plugin.version}</version>
  </dependency>
</dependencies>

我在努力解决这个问题。在我的例子中,我没有导入正确的@Test注释

1如果您使用的是junit 5,请检查@Test是否来自org.junit.jupiter.api.Test

2对于Junit5而不是@RunWithSpringRunner.class,请使用@ExtendWithSpringExtension.class

如果您使用创建了一个Spring启动应用程序,那么测试可以从Intellij Idea正常运行。 但是,如果尝试从命令行运行测试:

mvn clean test
您可能会感到惊讶,根本没有运行任何测试。我尝试添加surefire插件,但没有成功。 答案很简单:pom.xml包含以下依赖项:

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
           <exclusion>
              <groupId>org.junit.vintage</groupId>
              <artifactId>junit-vintage-engine</artifactId>
           </exclusion>
        </exclusions>
     </dependency>
排除的junit vintage引擎专用于保持与junit 4.x的向后兼容性。因此,新版本的Spring启动初始值设定项在默认情况下不支持它。
在我删除排除后,Maven开始查看项目的测试。

Maven Surefire插件支持多个测试框架。它尝试自动检测您正在使用的框架,然后查找使用该框架编写的测试。如果该自动检测被混淆,并且选择了错误的框架,那么第二阶段将找不到您的测试

自动检测的工作原理是扫描类路径,查找它所支持的测试框架中是否存在重要的驱动程序类。因此,如果POM或depended-on模块对其中一个驱动程序类具有不正确的依赖关系,则自动检测可能出错

目前,一个特殊的问题是JUnit4和JUnit5之间的差异。Surefire插件将它们视为不同的框架。但是由于包名称的相似性,一个项目可能依赖于错误的框架,但在一次偶然的检查中似乎是可以的


特别要注意的是,junit平台控制台适用于JUnit5,而junit平台运行程序适用于JUnit4。如果您的项目依赖于后者,Surefire将不会运行JUnit 5测试。

在我的情况下,我的父pom有一个父pom:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>some version</version>
    <relativePath/>
</parent>
更改为导入弹簧pom后:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>some version</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

我的单元测试开始运行

可能不是一个常见的错误,但除了用户的答案之外。除了要求您的方法公开之外:

您的方法也应该是无效的,当然有@Test注释

这行不通:

@试验 公共食品贸易{ //省略 } 它必须返回一个空值:

@试验 公共食品交易{ //省略 }
我发现更改maven配置更具吸引力。此命名约定确实会对未过期的用户造成一些危险。将您的测试用例命名为SomethingTest1,SomethingTest2会导致测试没有被执行。Maven不能这样做是为了向后兼容,但它确实有更多的逻辑来搜索所有文件中的测试用例。我从来都不知道这一点——有两个案例以测试结束,Maven拒绝运行它们……改为测试,棒棒糖公会的一切又好了。谢谢。@Tobias我同意你关于命名惯例带来的危险的观点。它还打破了使用注释所隐含的模式。使用注释的一个隐含结果是可以搜索具有特定注释的类/方法。我希望Maven没有设置命名约定限制,而是只在任何类中扫描@Test注释的方法!问:那么,如果您必须遵循test*约定,为什么还要用@test注释呢?这更多是一个java配置问题,但除了命名测试之外

正确初始化并将测试文件放在src下的测试目录中,测试类的包名必须与正在测试的类的包名匹配。@Paul False-Maven将执行。包约定用于结构和允许测试访问包私有方法。谢谢!这和在pom.xml文件中将作用域设置为test对我有帮助。正确的答案是TestThank,这是我的问题,由于你的评论,我解决了它。非常好的建议!演示了将单个模块Maven工件拆分为多个时“复制粘贴”的危险。我希望Maven打印一条消息-包类型为pom-因此不运行测试-为开发人员提供一些线索:出色的发现!应该有个测试默认排除项是:*/AbstractTest.java*/AbstractTestCase.java``它似乎也忽略了*/TestAbstractSomeClassName.java。我得到了一个junit-platform-surefire-provider的not found。请注意,对于surefire 2.22,不必添加对surefire provider或jupiter引擎工件的依赖关系。至少在没有它们的情况下,我的测试似乎运行得很好。请参阅。还值得注意的是,在使用此插件时,必须使用org.junit.jupiter.api.Test而不是org.junit.Test,否则将找不到这些测试。当surefire插件与junit 5一起添加时,这些测试是有效的dependencies@austin_ce就这样!同时,这使得它与mockito@Mock不兼容,整个测试模块变得无用:现在需要解决这个问题:这也是我遇到的问题,出于某种原因IntelliJ正在创建包私有的测试,Maven无法看到它们。将类和@Test方法更改为public使maven执行测试。解决了我的问题!注意,这不适用于JUnit5+。我猜IntelliJ的代码生成器假定您使用的是最新版本。@lamino我使用的是junit5,但它失败了,因为我的测试方法不公开。IntelliJ有点厚颜无耻地告诉我,这些方法可以是包私有的。我想SpringBoot只包括它使用的内容。您必须根据需要指定依赖项,这是有道理的。否则,您将导入一大堆您不使用的库。谢谢。在您的示例中,包括junit jupiter api和junit jupiter引擎。使用同样的方法,我在构建阶段出现了一些错误。但是,通过您提供的链接,我了解到只包含junit jupiter 5.6.2版可以很好地工作。这对我也很有用。我在build标记下添加了这个属性,这使得maven将测试类编译到名为testclasses的文件夹下的目标文件夹中。这是surefire插件为运行测试而检查的默认目录。大帮助。谢谢默认的运行程序是JUnit5,即使您可以从上下文菜单手动运行测试,它也不会在终端中工作,除非您删除您提到的排除项。我没有排除项,但必须明确指定依赖项junit引擎。我认为这是含蓄的,但事实并非如此。我也有同样的问题。谢谢我想:为什么这不跑呢。一些评论实际上建议排除junit vintage…类文件被编译为与测试源文件无关的.Class。我指的是测试类,当我说Class不是指文件类型时,您误解了。我会把我的答案弄清楚的谢谢-这只是对我们有效的十几个解决方案中的一个。这就解释了为什么要使用它:我几分钟前在Surefire文档中读到过它,所以一旦看到这个答案,我就决定立即尝试。现在执行的是1120而不是150,这听起来是一个不错的进步,但离运行所有的测试还有很长的路要走……对于我来说,在使用org.junit.jupiter.api.Test之后工作。我不需要使用@ExtendWithSpringExtension.class对于使用spring boot的人,请帮我检查IntelliJ试图帮我做一些事情,但破坏了测试。如果我对Junit Jupiter有正确的依赖关系,对SureFire插件有正确的插件版本,并且我对类名使用ALT+ENTER来创建测试,maven将无法识别测试类,也不会运行它。但是,当我根据Maven命名约定手动创建测试文件时,它将被Maven识别并运行。我还没有弄清楚如何逆转IntelliJ破坏测试的过程
<build>
    <testSourceDirectory>test</testSourceDirectory>
<build>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.0</version>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.22.0</version>
        </plugin>
    </plugins>
</build>
<!-- ... -->
<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    <!-- ... -->
</dependencies>
<!-- ... -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
  <dependency>
    <groupId>org.apache.maven.surefire</groupId>
    <artifactId>surefire-junit47</artifactId>
    <version>${maven-surefire-plugin.version}</version>
  </dependency>
</dependencies>
import org.junit.jupiter.api.Test;

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application.properties")    
public class CotacaoTest {
    @Test
    public void testXXX() {

    }
}
mvn clean test
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
           <exclusion>
              <groupId>org.junit.vintage</groupId>
              <artifactId>junit-vintage-engine</artifactId>
           </exclusion>
        </exclusions>
     </dependency>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>some version</version>
    <relativePath/>
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>some version</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>