Search code examples
javamavenkotlinjunitmaven-surefire-plugin

pom.xml Maven configuration to run JUnit 4 + JUnit 5 Jupiter tests in mixed Java + Kotlin project


I cannot configure maven project successfully to run mixed JUnit 4 / JUnit 5 Jupiter tests for Java and Kotlin.

I have no problems to configure Gradle (for instance this configuration works well for my needs), but not maven. I have tried different configurations of maven, Kotlin, surefire plugins with different versions of JUnit Jupiter and platform dependencies, but wasn't success...

Can anyone of you provide worked example?

I have also posted similar questions on JUnit team GitHub issues and in Kotlin slack channel: - https://github.com/junit-team/junit5/issues/1899 - https://kotlinlang.slack.com/archives/C0922A726/p155880442804330


Regards, Maksim


Solution

  • Okay... I spent couple of hours and seems like I found answer. Here example of worked pom.xml file for multi-module maven project to execute mixed JUnit 4 Vintage and JUnit 5 Jupiter tests together with mixed Java and Kotlin test classes with limitations described like so:

    src/
      test/
        java/
          **/*JUnit4VintageJavaTest.java  +
          **/*JUnit4VintageKotlinTest.kt  +
          **/*JUnit5JupiterJavaTest.java  +
          **/*JUnit5JupiterKotlinTest.kt  +
        kotlin/
          **/*JUnit4VintageJavaTest.java  -
          **/*JUnit4VintageKotlinTest.kt  +
          **/*JUnit5JupiterJavaTest.java  -
          **/*JUnit5JupiterKotlinTest.kt  +
    

    where

    + means: tests are going to be executed

    - means: for some reasons test are not going to be executed with provided configuration...

    pom.xml file:

    <?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/maven-v4_0_0.xsd">
    
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.github.daggerok</groupId>
      <artifactId>mixed-kotlin-java-jupiter-tests-maven-execution</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>pom</packaging>
    
      <!--
      <modules>
        <module>module-1</module>
        <module>module-2</module>
      </modules>
      -->
    
      <properties>
        <java.version>1.8</java.version>
        <kotlin.version>1.3.31</kotlin.version>
        <junit-jupiter.version>5.5.0-M1</junit-jupiter.version>
        <junit-platform.version>1.5.0-M1</junit-platform.version>
    
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    
        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.0.0-M3</maven-surefire-plugin.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.jetbrains.kotlin</groupId>
          <artifactId>kotlin-stdlib</artifactId>
          <version>${kotlin.version}</version>
        </dependency>
    
        <!-- junit 4 -->
        <dependency><!-- already contains junit:4.12 dependency, so we are not going to add it explicitly! -->
          <groupId>org.jetbrains.kotlin</groupId>
          <artifactId>kotlin-test-junit</artifactId>
          <version>${kotlin.version}</version>
          <scope>test</scope>
        </dependency>
        <dependency><!-- vintage engine is required if you wanna execute JUnit 4 together with JUnit 5 Jupiter tests... -->
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
          <version>${junit-jupiter.version}</version>
          <scope>test</scope>
        </dependency>
    
        <!-- junit 5 -->
        <dependency>
          <groupId>org.jetbrains.kotlin</groupId>
          <artifactId>kotlin-test-junit5</artifactId>
          <version>${kotlin.version}</version>
          <scope>test</scope>
          <!-- includes junit-jupiter-api:5.0.0 and junit-jupiter-engine:5.2.0, but we need other versions -->
            <exclusions>
                <exclusion>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency><!-- includes junit-jupiter-api and junit-jupiter-engine dependencies -->
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <defaultGoal>test</defaultGoal>
    
        <plugins>
          <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>${kotlin.version}</version>
            <configuration>
              <experimentalCoroutines>enable</experimentalCoroutines>
            </configuration>
            <executions>
              <execution>
                <id>compile</id>
                <phase>compile</phase>
                <goals>
                  <goal>compile</goal>
                </goals>
                <configuration>
                  <sourceDirs>
                    <sourceDir>${project.basedir}/src/main/java</sourceDir>
                    <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
                  </sourceDirs>
                </configuration>
              </execution>
              <execution>
                <id>test-compile</id>
                <phase>test-compile</phase>
                <goals>
                  <goal>test-compile</goal>
                </goals>
                <configuration>
                  <sourceDirs>
                    <sourceDir>${project.basedir}/src/test/java</sourceDir>
                    <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
                  </sourceDirs>
                </configuration>
              </execution>
            </executions>
          </plugin>
    
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <executions>
              <execution>
                <id>default-compile</id>
                <phase>none</phase>
              </execution>
              <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>${maven-surefire-plugin.version}</version>
          </plugin>
        </plugins>
      </build>
    
    </project>
    

    worked example located here

    how to verify:

    git clone https://github.com/daggerok/mixed-kotlin-java-jupiter-tests testme ; cd $_ ; mvn test
    

    Only question cannot answer if it's possible and how to configure maven project where allowed place and recognize java test classes in src/test/kotlin test sources directory? But seems like it's a different question and that one must be closed.

    my PR with according sample was just merged to junit-team/junit5-samples project and available here