Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin - Maven not executing tests

I have a Kotlin application which I want to test. My tests (.kt) files execute with success in Eclipse. (The test itself is a h2 mock jdbc test).

Now when running mvn test -X it says:

 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

And it doesn't execute any test (It can't find em)

Here's my 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>
like image 284
Ivar Reukers Avatar asked Sep 27 '16 11:09

Ivar Reukers


1 Answers

Two problems, the first issue you found yourself but I'll document here. In the Kotlin-Maven plugin you have the settings for test-compile goal as:

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

Which is compiling the src/main/java directory instead of src/test/java so your tests are not being compiled at all. Should be:

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

Or if your files are both in the java and kotlin directories:

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

The second issue is likely you trying to work around the first one. And it looks fine on the surface but is incorrect configuration of the Surefire plugin. The documentation for the Maven Surefire plugin isn't quite accurate (or it isn't complete about how it works). If you remove your Surefire plugin configuration completely it will work because the defaults already do what you want. Or you can change from listing the include file patterns from having the .kt suffix instead to .class or .java suffixes and those will work fine even for Kotlin, Clojure, Scala, ...

Why? here is the story...

This configuration:

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

Doesn't do what you think it does. This is actually converted in Surefire by doing a search and replace on .java to .class, and internally becomes:

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

But if you use the .kt extension you break this hard coded magic. You can see it in the source code of Surefire plugin where it replaces files that end with .java with .class. Ooops, it has nothing to do with source files at all and is looking for compiled classes.

In Surefire plugin 2.19 they added the ability to have regex and also fully qualified classname patterns. So the way the plugin decides which you are using seems to be by the filename extension .java. If it sees .java it knows that each .java file becomes a class of the same name, so instead it looks for the classes that match the pattern, not the source code. The source is already compiled by the compiler plugins, not the test runner. It has no business looking for source code.

So this setting is misleading and is really using "magic" to figure out a classname instead of just asking for classnames. Of course the samples and everything completely make you believe it is related to source files. It isn't.

It is better to use no configuration and follow the default naming convention. Or if you must specify something, use the more modern regex or class name version of the include configuration:

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

Which is now comparing to any class with those names in any package.

like image 148
6 revs Avatar answered Nov 24 '22 08:11

6 revs