raniejade / spek-idea-plugin

MIT License
48 stars 15 forks source link

Can't get Spek to run single tests in Android Studio 3.0 #58

Closed Rosomack closed 6 years ago

Rosomack commented 6 years ago

Hi there,

We have a multi-module Android project with mixed android or plain java modules. We're now trying to migrate to kotlin and thought tests might be a good point to start. I'm trying to set everything up to run using JUnit 5.

I've managed to get Android module tests fully working in the IDE and the console. For java modules I managed to get 90% there - I hit a wall when debugging an issue when running a single Spek test from the IDE (clicking the play arrow in the gutter). The test always fails with:

objc[62378]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x104af24c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x104bba4e0). One of the two will be used. Which one is undefined.
Nov 15, 2017 10:32:07 PM org.junit.platform.launcher.core.DefaultLauncher handleThrowable
WARNING: TestEngine with ID 'spek' failed to discover tests
org.junit.platform.commons.util.PreconditionViolationException: Could not load class with name: com.babylon.systemsmodule.appointments.rate.AppointmentRatingInteractorSpec
    at org.junit.platform.engine.discovery.ClassSelector.lambda$getJavaClass$0(ClassSelector.java:71)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.junit.platform.engine.discovery.ClassSelector.getJavaClass(ClassSelector.java:70)
    at org.jetbrains.spek.engine.SpekTestEngine.resolveSpecs(SpekTestEngine.kt:79)
    at org.jetbrains.spek.engine.SpekTestEngine.discover(SpekTestEngine.kt:50)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:130)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:117)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at org.jetbrains.spek.tooling.runner.junit.JUnitPlatformSpekRunner.run(JUnitPlatformSpekRunner.kt:107)
    at org.jetbrains.spek.tooling.MainKt.main(Main.kt:58)

The root cause is a ClassNotFoundException.

The funny thing is, when I run all tests in the module the Spec gets executed along with the rest of JUnit4 tests. Running from the console also executes all the tests just fine.

This is my list of dependencies used to set the tests up:

apply plugin: 'org.junit.platform.gradle.plugin'
apply plugin: 'kotlin'

junitPlatform {
    filters {
        engines {
            include 'spek'
            include 'junit-vintage'// Configure the vintage (JUnit 4) TestEngine to be detected by JUnit 5
        }
    }
}

dependencies {
    testCompile projectDependencies.kotlin
    testCompile projectDependencies.kotlinReflect
    testCompile(projectDependencies.spekApi) {
        exclude group: 'org.jetbrains.kotlin'
    }
    testCompile(projectDependencies.spekDataDrivenExtension) {
        exclude group: 'org.jetbrains.kotlin'
    }
    testCompile (projectDependencies.spekJunitPlatformEngine) {
        exclude group: "org.junit.platform"
        exclude group: 'org.jetbrains.kotlin'
    }
    testRuntime("org.junit.platform:junit-platform-launcher:1.0.2")
    testRuntime("org.junit.platform:junit-platform-console:1.0.2")
    testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.1")
    testRuntime("org.junit.jupiter:junit-jupiter-api:5.0.1")
    testRuntime("org.junit.vintage:junit-vintage-engine:4.12.1")
    testCompile projectDependencies.kluent
    testCompile projectDependencies.mockitoKotlin
    testCompile projectDependencies.junit5EmbeddedRuntime
}
raniejade commented 6 years ago

Hi any reason why you have a plain old java module in an Android project?

wickedev commented 6 years ago

@Rosomack official junit 5 gradle plugin is not compatible with android project. instead use this one. https://github.com/mannodermaus/android-junit5

Rosomack commented 6 years ago

@raniejade We run something called Clean Architecture, our business logic is supposed to be android-independent and so sits in a plain Java module.

@WickeDev This is a plain Java module within an Android project, the official plugin should be compatible. The android one doesn't work at all with it.

raniejade commented 6 years ago

@Rosomack I see, do you have the latest plugin right? If yes, give me some time to look at it. Supporting AS is a nightmare for me, a lot of hacky stuff just to get proper integration.

Rosomack commented 6 years ago

@raniejade Yup, updated it just yesterday, v0.5.2-studio3.0. Thanks for your hard work on Spek support!

raniejade commented 6 years ago

@Rosomack can you try out this build if it works?

Rosomack commented 6 years ago

@raniejade WOW, thanks for the quick turnaround!

According to my testing it works, but there are a couple of hiccups. It randomly fails after a clean with this stacktrace:

Testing started at 18:20 ...
WARNING: TestEngine with ID 'spek' failed to discover tests
java.lang.NoClassDefFoundError: com/babylon/coremodule/appointments/model/AppointmentRatingRequest
    at com.babylon.systemsmodule.appointments.rate.AppointmentRatingInteractorSpec$1.invoke(AppointmentRatingInteractorSpec.kt:19)
    at com.babylon.systemsmodule.appointments.rate.AppointmentRatingInteractorSpec$1.invoke(AppointmentRatingInteractorSpec.kt:16)
    at org.jetbrains.spek.engine.SpekTestEngine.resolveSpec(SpekTestEngine.kt:121)
    at org.jetbrains.spek.engine.SpekTestEngine.resolveSpecs(SpekTestEngine.kt:80)
    at org.jetbrains.spek.engine.SpekTestEngine.discover(SpekTestEngine.kt:50)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:130)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:117)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at org.jetbrains.spek.tooling.runner.junit.JUnitPlatformSpekRunner.run(JUnitPlatformSpekRunner.kt:107)
    at org.jetbrains.spek.tooling.MainKt.main(Main.kt:58)
Caused by: java.lang.ClassNotFoundException: com.babylon.coremodule.appointments.model.AppointmentRatingRequest
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 10 more

Process finished with exit code 0
raniejade commented 6 years ago

I'm not sure if it's a problem with the plugin, I just used what AS3 provides. It just runs gradle to build the required modules.

Rosomack commented 6 years ago

OK, I'll keep digging. Thanks for the help!

Rosomack commented 6 years ago

Closing this as the original issue has been resolved. Thanks!