spekframework / spek

A specification framework for Kotlin
Other
2.23k stars 180 forks source link

Spek 1 Plugin compatibility with Android Studio 3.3.0 #571

Closed sraiteri closed 5 years ago

sraiteri commented 5 years ago

Hi Spek Framework team,

Our team is currently in the process of migrating an Android app from Spek 1 to Spek 2. It's a large codebase, so migration effort will be considerable (magnitude of months).

Android Studio 3.3.0 has been officially released earlier in the week and we've noticed an incompatibility with it and v0.5.5-studio-3.0 of the Spek plugin. We're holding off on full migration of our test codebase until Spek 2 matures out of RC.

Android Studio 3.3.0 throws the following exception when the plugin initialises:

Cannot read scheme SpecsRunConfiguration-Specs in **_ factoryName_ Spek - Android.xml

java.lang.NoClassDefFoundError: com/android/tools/idea/run/PreferGradleMake
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at com.intellij.util.lang.UrlClassLoader._defineClass(UrlClassLoader.java:278)
    at com.intellij.util.lang.UrlClassLoader.defineClass(UrlClassLoader.java:274)
    at com.intellij.util.lang.UrlClassLoader._findClass(UrlClassLoader.java:243)
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClassInsideSelf(PluginClassLoader.java:147)
    at com.intellij.ide.plugins.cl.PluginClassLoader.tryLoadingClass(PluginClassLoader.java:74)
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:61)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.jetbrains.spek.studio.SpekAndroidConfigurationFactory.createTemplateConfiguration(SpekAndroidConfigurationFactory.kt:15)
    at com.intellij.execution.configurations.ConfigurationFactory.createTemplateConfiguration(ConfigurationFactory.java:64)
    at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl.readExternal(RunnerAndConfigurationSettingsImpl.kt:204)
    at com.intellij.execution.impl.RunConfigurationSchemeManager.readData(RunConfigurationSchemeManager.kt:65)
    at com.intellij.execution.impl.RunConfigurationSchemeManager.createScheme(RunConfigurationSchemeManager.kt:48)
    at com.intellij.execution.impl.RunConfigurationSchemeManager.createScheme(RunConfigurationSchemeManager.kt:22)
    at com.intellij.configurationStore.LazySchemeProcessor.createScheme$default(scheme-impl.kt:69)
    at com.intellij.configurationStore.SchemeManagerImpl.loadScheme$intellij_platform_configurationStore_impl(SchemeManagerImpl.kt:321)
    at com.intellij.configurationStore.SchemeManagerImpl$loadSchemes$2.invoke(SchemeManagerImpl.kt:174)
    at com.intellij.configurationStore.SchemeManagerImpl$loadSchemes$2.invoke(SchemeManagerImpl.kt:42)
    at com.intellij.configurationStore.SchemeManagerIprProvider.processChildren(SchemeManagerIprProvider.kt:40)
    at com.intellij.configurationStore.SchemeManagerImpl.loadSchemes(SchemeManagerImpl.kt:172)
    at com.intellij.configurationStore.SchemeManagerImpl.reload(SchemeManagerImpl.kt:220)
    at com.intellij.execution.impl.RunManagerImpl.loadState(RunManagerImpl.kt:564)
    at com.intellij.execution.impl.RunManagerImpl.loadState(RunManagerImpl.kt:49)
    at com.intellij.configurationStore.ComponentStoreImpl.doInitComponent(ComponentStoreImpl.kt:356)
    at com.intellij.configurationStore.ComponentStoreImpl.initComponent(ComponentStoreImpl.kt:312)
    at com.intellij.configurationStore.ComponentStoreImpl.initPersistenceStateComponent(ComponentStoreImpl.kt:115)
    at com.intellij.configurationStore.ComponentStoreImpl.initComponent(ComponentStoreImpl.kt:90)
    at com.intellij.configurationStore.ComponentStoreWithExtraComponents.initComponent(ComponentStoreWithExtraComponents.kt:15)
    at com.intellij.openapi.components.impl.PlatformComponentManagerImpl.initializeComponent(PlatformComponentManagerImpl.java:54)
    at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.getComponentInstance(ServiceManagerImpl.java:212)
    at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:247)
    at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:214)
    at com.intellij.openapi.components.ServiceManager.doGetService(ServiceManager.java:47)
    at com.intellij.openapi.components.ServiceManager.getService(ServiceManager.java:30)
    at com.intellij.execution.impl.ProjectRunConfigurationInitializer.requestLoadWorkspaceAndProjectRunConfiguration(ProjectRunConfigurationInitializer.kt:47)
    at com.intellij.execution.impl.ProjectRunConfigurationInitializer.access$requestLoadWorkspaceAndProjectRunConfiguration(ProjectRunConfigurationInitializer.kt:24)
    at com.intellij.execution.impl.ProjectRunConfigurationInitializer$1.projectComponentsInitialized(ProjectRunConfigurationInitializer.kt:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:117)
    at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:426)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:387)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:376)
    at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:357)
    at com.intellij.util.messages.impl.MessageBusImpl.access$200(MessageBusImpl.java:43)
    at com.intellij.util.messages.impl.MessageBusImpl$2.invoke(MessageBusImpl.java:208)
    at com.sun.proxy.$Proxy49.projectComponentsInitialized(Unknown Source)
    at com.intellij.openapi.project.impl.ProjectImpl.init(ProjectImpl.java:281)
    at com.intellij.openapi.project.impl.ProjectManagerImpl.initProject(ProjectManagerImpl.java:281)
    at com.intellij.openapi.project.impl.ProjectManagerImpl.lambda$loadProjectWithProgress$13(ProjectManagerImpl.java:547)
    at com.intellij.openapi.progress.impl.CoreProgressManager$1.run(CoreProgressManager.java:218)
    at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:736)
    at com.intellij.openapi.progress.impl.CoreProgressManager$5.run(CoreProgressManager.java:434)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:580)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
    at com.intellij.openapi.application.impl.ApplicationImpl.lambda$null$10(ApplicationImpl.java:574)
    at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.android.tools.idea.run.PreferGradleMake PluginClassLoader[org.jetbrains.spek.spek-idea-plugin, 0.5.5-studio3.0] com.intellij.ide.plugins.cl.PluginClassLoader@4c87f89f
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:63)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 69 more

Ideally, we'd like to upgrade to the Android Studio 3.3.0 but running tests from the IDE is a blocker. No issues to report with Spek Framework plugin and the tests already ported over to Spek 2.

screen shot 2019-01-18 at 11 07 38 am

Is it possible to get a bug fix for the Spek plugin so it works with Android Studio 3.3.0?

sraiteri commented 5 years ago

Also cross-referencing https://github.com/raniejade/spek-idea-plugin/issues/71 and https://github.com/raniejade/spek-idea-plugin/issues/68

raniejade commented 5 years ago

Can you guys test this build out? 0.6.1-studio3.3.zip

sraiteri commented 5 years ago

@raniejade,

0.6.1-studio3.3.zip works with Android Studio 3.3.0 (under the following configurations):

screen shot 2019-01-19 at 9 47 32 pm
  1. AGP 3.3.0, Gradle 5.1.1, Spek 1.2.1

    • Run all Spek 1 tests in test package from IDE :white_check_mark:
    • Run individual Spek 1 test files from IDE :white_check_mark:
  2. AGP 3.2.1, Gradle 4.10.3, Spek 1.2.1

    • Run all Spek 1 tests in test package from IDE :white_check_mark:
    • Run individual Spek 1 test files from IDE :white_check_mark:

Thanks very much for the very fast resolution 😄 !

CACuzcatlan commented 5 years ago

@raniejade how do you install that manually? I've only done it through Android Studio -> Preferences -> Plugins

raniejade commented 5 years ago

@CACuzcatlan there should be an option to install from disk.

sraiteri commented 5 years ago

@CACuzcatlan that's the one.

Android Studio -> Preferences -> Plugins -> Install plugin from disk... (bottom right button)

image

After the standard Android Studio restart to initialise the plugin, you should see 0.6.1-studio3.3 is installed:

image

CACuzcatlan commented 5 years ago

@sraiteri Thanks! Unfortunately, I'm still getting the issue where it says Nothing Here when clicking on the gutter arrow in Android Studio. I'm running

Android Studio 3.3 AGP 3.3.0, Gradle 5.1.1, Spek 1.2.1

sraiteri commented 5 years ago

@CACuzcatlan - very strange. Do you have any test plugins competing at the JUnit platform level? What is the structure of your given/on/it?

Here's what I see when I try to run individual tests in a Spek 1 test file:

image

Occasionally I've got to try to re-run from the gutter again, but the tests all run as expected.

CACuzcatlan commented 5 years ago

@sraiteri I have that exact setup and I know it's not the tests because they were working before I upgraded to Android Studio 3.3.

I'm using Gradle Plugin 3.3.0, Gradle 5.1.1, Spek 1.2.1, Spek plugin 0.6.1-studio3.3

Android Studio 3.3 Build #AI-182.5107.16.33.5199772, built on December 24, 2018 JRE: 1.8.0_152-release-1248-b01 x86_64 JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o macOS 10.13.6

It's definitely an issue that started with AS 3.3 since nothing else has changed. The gutter always says Nothing here. I've tried cleaning, invalidate cache/restart, reboot computer, etc. The tests run from terminal, but not from Android Studio. Doesn't matter which test file I try, all of them say Nothing here in the gutter.

raniejade commented 5 years ago

@CACuzcatlan what kotlin plugin version are you using?

CACuzcatlan commented 5 years ago

@raniejade The one from Android Studio -> Preferences -> Plugins 1.3.20-release-Studio3.3.1

In my gradle file under dependencies I had: classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11"

I was getting the following warning: Kotlin version that is used for building with Gradle (1.3.11) differs from the one bundled into the IDE plugin (1.3.20) more... (⌘F1)

so I change it to 1.3.20 and synced. The build completed without errors but I still see Nothing here from the green arrow in the gutter.

raniejade commented 5 years ago

@CACuzcatlan Are you able to share the project? If not, can you create a sample project that replicates the issue?

sraiteri commented 5 years ago

I'm not sure if this issue is Kotlin related - I have had similar issues before in other projects. Tests ran as part of Gradle fine, but failed to be detected from the IDE (the Nothing here from plugin execution.

In most cases, it came down to some exclude group: org.junit.platform items scattered through the test dependencies - legacy configuration to force the JUnit platform versions in older dependencies to align correctly. If you're testing with multiple test frameworks (this one had JUnit Vintage, JUnit Jupiter & Spek 1), the configuration can be a little to align the org.junit.platform versions correctly and get everything running together.

Here's the test plugins and dependency versions I've got in the project which works (above). It uses Spek 1, Spek 2 & JUnit Jupiter:

// Plugin (buildscript)
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.3.2.0"

...

// Test dependencies
// Spek 1
testImplementation "org.jetbrains.spek:spek-api:1.2.1"
testImplementation "org.jetbrains.spek:spek-junit-platform-engine:1.2.1"
testImplementation "org.jetbrains.spek:spek-subject-extension:1.2.1"

// Spek 2
testImplementation "org.spekframework.spek2:spek-dsl-jvm:2.0.0-rc.1"
testImplementation "org.spekframework.spek2:spek-runner-junit5:2.0.0-rc.1"

// JUnit Jupiter (JUnit 5)
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.2"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.2"

// Pact tests (JUnit 5)
testImplementation "au.com.dius:pact-jvm-consumer-junit5_2.12:3.6.1"

...

Project is using Kotlin 1.3.20 as well.