Kotlin - Maven 不执行测试

Kotlin - Maven not executing tests

我有一个要测试的 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>

两个问题,第一个问题你自己找的,但我会在这里记录。在 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>

并不像您认为的那样。这实际上是通过在 .java 上搜索并替换为 .class 在 Surefire 中转换为:

            <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糟糕,它与源文件完全无关,正在寻找已编译的 classes.

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

所以此设置具有误导性,实际上是使用 "magic" 计算出 class 名称,而不是仅仅询问 class 名称。当然,示例和所有内容完全让您相信它与源文件有关。不是。

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

        <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>

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