【问题标题】:Kotlin - Maven not executing testsKotlin - Maven 不执行测试
【发布时间】:2016-09-27 11:41:38
【问题描述】:

我有一个想要测试的 Kotlin 应用程序。我的测试 (.kt) 文件在 Eclipse 中成功执行。 (测试本身是h2 mock jdbc 测试)。

现在在运行mvn test -X 时会显示:

 releases: [enabled => true, update => never]
]
[DEBUG]   (s) reportFormat = brief
[DEBUG]   (s) reportsDirectory = C:\Users\Ivar\workspace\anotherworkspace\newrestservice\complete\target\surefire-reports
[DEBUG]   (f) rerunFailingTestsCount = 0
[DEBUG]   (f) reuseForks = true
[DEBUG]   (s) runOrder = filesystem
[DEBUG]   (f) shutdown = testset
[DEBUG]   (s) skip = false
[DEBUG]   (f) skipAfterFailureCount = 0
[DEBUG]   (s) skipTests = false
[DEBUG]   (s) suiteXmlFiles = []
[DEBUG]   (s) testClassesDirectory = C:\Users\Ivar\workspace\anotherworkspace\newrestservice\complete\target\test-classes
[DEBUG]   (s) testFailureIgnore = false
[DEBUG]   (s) testNGArtifactName = org.testng:testng
[DEBUG]   (s) testSourceDirectory = C:\Users\Ivar\workspace\anotherworkspace\newrestservice\complete\src\test\java
[DEBUG]   (s) threadCountClasses = 0
[DEBUG]   (s) threadCountMethods = 0
[DEBUG]   (s) threadCountSuites = 0
[DEBUG]   (s) trimStackTrace = true
[DEBUG]   (s) useFile = true
[DEBUG]   (s) useManifestOnlyJar = true
[DEBUG]   (s) useSystemClassLoader = true
[DEBUG]   (s) useUnlimitedThreads = false
[DEBUG]   (s) workingDirectory = C:\Users\Ivar\workspace\anotherworkspace\newrestservice\complete
[DEBUG]   (s) project = MavenProject: org.springframework:gs-rest-service:0.1.0 @ C:\Users\Ivar\workspace\anotherworkspace\newrestservice\complete\pom.xml

并且它不执行任何测试(它找不到 em)

这是我的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-rest-service</artifactId>
    <version>0.1.0</version>
    <packaging>war</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <!--  <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>-->
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1211</version><!--$NO-MVN-MAN-VER$ -->
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.191</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-reflect -->


    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>1.0.3</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version><!--$NO-MVN-MAN-VER$ -->
                <executions>
                    <!-- Replacing default-compile as it is treated specially by maven -->
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <!-- Replacing default-testCompile as it is treated specially by maven -->
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>java-compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>java-test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.19.1</version><!--$NO-MVN-MAN-VER$-->
                    <configuration>
                        <includes>
                            <include>**/Test*.kt</include>
                            <include>**/*Test.kt</include>
                            <include>**/*TestCase.kt</include>
                        </includes>
                    </configuration>
                </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

【问题讨论】:

  • Maven 文档通常对设置、它们的使用以及它们的含义不是很清楚。您遇到了 Maven 文档不足的典型示例。我的回答说明了问题...

标签: maven unit-testing kotlin maven-surefire-plugin


【解决方案1】:

两个问题,第一个问题是你自己发现的,但我会在这里记录。在 Kotlin-Maven 插件中,test-compile 目标的设置为:

<execution>
      <id>test-compile</id>
      <goals>
          <goal>test-compile</goal>
      </goals>
      <configuration>
          <sourceDirs>
               <sourceDir>${project.basedir}/src/main/java</sourceDir>
          </sourceDirs>
      </configuration>
</execution>

编译的是src/main/java 目录而不是src/test/java,所以你的测试根本没有被编译。应该是:

          <sourceDirs>
               <sourceDir>${project.basedir}/src/test/java</sourceDir>
          </sourceDirs>

或者,如果您的文件同时位于 javakotlin 目录中:

          <sourceDirs>
               <sourceDir>${project.basedir}/src/test/java</sourceDir>
               <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
          </sourceDirs>

第二个问题可能是您试图解决第一个问题。表面上看起来还不错,但是 Surefire 插件的配置不正确。 Maven Surefire 插件的文档不是很准确(或者它的工作原理并不完整)。如果您完全删除您的 Surefire 插件配置,它将起作用,因为默认值已经满足您的要求。或者,您可以将列出 include 文件模式从具有 .kt 后缀改为 .class.java 后缀,即使对于 Kotlin、Clojure、Scala 等,这些模式也可以正常工作...

为什么?这是故事......

这个配置:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <includes>
                    <include>**/Test*.java</include>
                    <include>**/*Test.java</include>
                    <include>**/*TestCase.java</include>
                    <include>**/RandomName.java</include>
                </includes>
            </configuration>
        </plugin>

不做你认为它做的事。这实际上是在 Surefire 中通过在 .java 上搜索和替换到 .class 来转换的,并且在内部变为:

            <configuration>
                <includes>
                    <include>**/Test*.class</include>
                    <include>**/*Test.class</include>
                    <include>**/*TestCase.class</include>
                    <include>**/RandomName.class</include>
                </includes>
            </configuration>

但是,如果您使用 .kt 扩展名,您将打破这种硬编码的魔力。您可以在source code of Surefire plugin 中看到它,它将以.java 结尾的文件替换为.class哎呀,和源文件完全没有关系,正在寻找编译好的类。

在 Surefire 插件 2.19 中,他们添加了拥有 regex and also fully qualified classname patterns 的功能。所以插件决定你使用哪个的方式似乎是通过文件扩展名.java。如果它看到.java,它就知道每个.java 文件都会变成一个同名的类,因此它会寻找与模式匹配的类,而不是源代码。源代码已经由编译器插件编译,而不是测试运行器。它没有业务寻找源代码。

因此,此设置具有误导性,实际上是在使用“魔术”来计算类名,而不仅仅是询问类名。当然,样本和一切都完全让您相信它与源文件有关。不是。

最好不使用任何配置并遵循默认命名约定。或者,如果您必须指定某些内容,请使用include 配置的更现代的正则表达式或类名版本:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <includes>
                    <include>Test*</include>
                    <include>*Test</include>
                    <include>*TestCase</include>
                    <include>RandomName</include>
                </includes>
            </configuration>
        </plugin>

现在与任何包中具有这些名称的任何类进行比较。

【讨论】:

  • 原来这不是问题,问题是没有编译测试(maven 插件编译器sourceDir)。您的(非常详细和解释性的)回答帮助我解决了问题,所以我会接受它!
  • @Ivaro18 如果编译,*.kt 的包含是否真的有效?我认为这仍然失败是吗?
  • 不确定,我在添加sourceDir之前将其更改为类名版本
  • 更新了答案,包括 src/main/java 与 src/main/test 问题
  • 在完成这些故障排除步骤后,我发现了我的 java 测试,但仍未找到 kotlin 测试。我验证了类文件正在生成。在我的情况下,我使用的是 JUnit5 并且缺少 junit-jupiter-engine 依赖项。使用该设置确保您的 maven-surefire-pluginjunit-jupiter-* 依赖项的版本兼容。我们已经达到了最新版本可能会很好用的地步。今天我使用3.0.0-M35.5.0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多