Gradle for Android: Why doesn't javaexec pick

2019-08-26 21:23发布

I have an Android project (on Windows) where I am trying to run cucumber-jvm as a non-instrumented "unit test". I.e. execute Cucumber features when I run gradlew test.

Here are the relevant bits of my app's build.gradle:

android {
    ...
    testOptions {
        unitTests.all {
            javaexec {
                main = "cucumber.api.cli.Main"
                classpath = getClasspath()
                args = ['--plugin', 'pretty', '--glue', 'gradle.cucumber', 'src/test/java/cucumber/assets']
            }
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    testImplementation 'io.cucumber:cucumber-java:3.0.2'
    testImplementation 'io.cucumber:cucumber-junit:3.0.2'
}

When I run gradlew test --info at the command-line I get the following error:

Starting process 'command 'C:\Program Files\Java\jdk1.8.0_162\bin\java.exe''. Working directory: C:\dev\urig\android-cucumber\app Command: C:\Program Files\Java\jdk1.8.0_162\bin\java.exe -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant cucumber.api.cli.Main --plugin pretty --glue gradle.cucumber src/test/java/cucumber/assets
Successfully started process 'command 'C:\Program Files\Java\jdk1.8.0_162\bin\java.exe''
Error: Could not find or load main class cucumber.api.cli.Main

It looks to me like the command contains no classpath and my question is - Why?

PS - I've verified that at the time of the call to javaexec the call to getClasspath() indeed contains all the dependencies with this little bit of Groovy: println getClasspath().any { println it }

PPS - I know the intended use of cucumber-jvm is for instrumented tests using cucumber-android. I have a specific use case for running Cucumber as a "local unit test" (Android terms, not mine) so the above doesn't quite help me.

1条回答
倾城 Initia
2楼-- · 2019-08-26 21:50

I believe I've found a solution for my issue. Here's the code that works for me:

testOptions {
    unitTests.all {
        def classpath2 = getClasspath()
        javaexec {
            main = "cucumber.api.cli.Main"
            classpath = classpath2
            args = ['--plugin', 'pretty', '--glue', 'gradle.cucumber', 'src/test/java/cucumber/assets']
        }
    }
}

It seems to me that my original call to getClassPath() inside the javaexec closure was returning an empty file collection. At the same time, in the closure for unitTests.all, getClassPath() contains the correct classpath.

By passing the classpath from the external closure into the internal closure via a variable, cucumber.api.cli.Main now runs successfully and my Cucumber features run as part of the Gradle test task.

查看更多
登录 后发表回答