3
votes

After adding org.junit.platform.gradle.plugin into the build and migrating everything from junit4 Gradle started to break with below error.

All runs fine with the vintage runner but junit5 tests are not.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':server:junitPlatformTest'.

Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'C:\Program Files\Java\jdk1.8.0_131\bin\java.exe''
...
Caused by: java.io.IOException: CreateProcess error=206, The filename or extension is too long

Do I need to configure the junit5 test consumer somehow to deal with this sort of things? or maybe there is some uber jar handling those?


EDIT1

I have a suspicion this might be the classpath, im going to generate an uberjar with all junit modules.


EDIT2

Looking into the source code seems like Junit plugin adds loads to the classpath

// Note: the user's test runtime classpath must come first; otherwise, code
// instrumented by Clover in JUnit's build will be shadowed by JARs pulled in
// via the junitPlatform configuration... leading to zero code coverage for
// the respective modules.
classpath = project.sourceSets.test.runtimeClasspath + project.configurations.junitPlatform

Im curious if I could wipe out this configuration junitPlatform after the project evaluate as all JUnit dependencies are added anyway for the code to compile, then the plugin is just adding loads on the top. And I created a project that wraps all Junit5 libs inside one artefact.


EDIT3

I did manage to pack up all jupiter artefacts into 1 to shrink the cp a little, but still my classpath goes over 35k which is a bit weird

How does gradle run junit5 tests then? seems like it puts all transitives from all other projects related, and adds them the cp, which then brakes with error=206

1

1 Answers

2
votes

GRADLE 4.6 SUPPORTS JUNIT 5! Remember that vintage engine need to be same version as the jupiter now Edited: 16/03/2018


I have managed to make it all working with below code.

it is going to produce a jar with a manifest and put that jar on the classpath.

It's not using any plugins just running the platform as a javaExec task.

This file needs to be applied to the project you want to run your test on.

def version = "5.0.1"
def platformVersion = "1.0.1"
def vintageVersion = "4.12.1"
def projectCp = "${project.name}Classpath.jar"

dependencies {

    compile "org.junit.jupiter:junit-jupiter-api:$version"
    compile "org.junit.platform:junit-platform-launcher:$platformVersion"
    compile "org.junit.platform:junit-platform-runner:$platformVersion"

    testCompile "junit:junit:4.12"

    testCompile "org.junit.jupiter:junit-jupiter-params:$version"

    testRuntime "org.junit.vintage:junit-vintage-engine:$vintageVersion"
    testRuntime "org.junit.platform:junit-platform-console:$platformVersion"
    testRuntime "org.junit.jupiter:junit-jupiter-engine:$version"
}

afterEvaluate {
    if (!project.tasks.findByName('packClasspath')) {
        task packClasspath(type: Jar) {
            archiveName = projectCp
            version = ''
            manifest {
                attributes 'Class-Path':
                project.configurations.testRuntime.collect { "file:///${it.absolutePath}" }.join(' ')}

            }
        }

        if (!project.tasks.findByName('jupiterTest')) {
            task jupiterTest(type: JavaExec) {
                jvmArgs '-ea'
                classpath = files(
                    "${project.buildDir}\\libs\\${projectCp}",
                    project.sourceSets.test.output,
                    project.sourceSets.main.output,
                )

                main 'org.junit.platform.console.ConsoleLauncher'
                args '--scan-class-path'
                args "--reports-dir=$project.testReportDir"
            }
        }

        test.dependsOn jupiterTest
        jupiterTest.dependsOn packClasspath
        jupiterTest.dependsOn testClasses

        test.enabled = false

}

Alternatively, now you can use this plugin which does the above, just apply it to the project with too long classpath.

https://github.com/viswaramamoorthy/gradle-util-plugins

Edit

GRADLE 4.6 SUPPORTS JUNIT 5!