cashapp / paparazzi

Render your Android screens without a physical device or emulator
https://cashapp.github.io/paparazzi/
Apache License 2.0
2.28k stars 214 forks source link

Could not complete execution for Gradle Test Executor: `de.mannodermaus.android-junit5` #744

Open timrijckaert opened 1 year ago

timrijckaert commented 1 year ago

Description When applying the de.mannodermaus.android-junit5 plugin the project breaks. Many Android project still rely on this plugin for other unit tests.

The version of the de.mannodermaus.android-junit5 plugin tested is: 1.8.2.1

org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not complete execution for Gradle Test Executor 1.
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:64)
    at java.base@11.0.11/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base@11.0.11/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base@11.0.11/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base@11.0.11/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.junit.platform.commons.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath
    at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:296)
    at org.junit.platform.launcher.core.DefaultLauncher.<init>(DefaultLauncher.java:55)
    at org.junit.platform.launcher.core.LauncherFactory.createDefaultLauncher(LauncherFactory.java:134)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:125)
    at org.junit.platform.launcher.core.LauncherFactory.create(LauncherFactory.java:109)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:97)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    ... 18 more

Steps to Reproduce

Apply following diff to the sample project.

Index: sample/build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/sample/build.gradle b/sample/build.gradle
--- a/sample/build.gradle   (revision 9e4684a5a180a52cef543efbe0a6d26af3aaea1e)
+++ b/sample/build.gradle   (date 1680019501474)
@@ -1,6 +1,7 @@
 apply plugin: 'com.android.library'
 apply plugin: 'org.jetbrains.kotlin.android'
 apply plugin: 'app.cash.paparazzi'
+apply plugin: 'de.mannodermaus.android-junit5'

 android {
   namespace 'app.cash.paparazzi.sample'
Index: build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/build.gradle b/build.gradle
--- a/build.gradle  (revision 9e4684a5a180a52cef543efbe0a6d26af3aaea1e)
+++ b/build.gradle  (date 1680019501476)
@@ -13,6 +13,7 @@
     classpath libs.plugin.android
     classpath libs.plugin.versions
     classpath libs.plugin.spotless
+    classpath "de.mannodermaus.gradle.plugins:android-junit5:1.8.2.1"

     // Normally you would declare a version here, but we use dependency substitution in
     // settings.gradle to use the version built from inside the repo.

Expected behavior The Paparazzi plug-in and the Junit5 plugin can live happily together.

Additional information:

Screenshots n/a

Thanks in advance

TWiStErRob commented 1 year ago

Hi, looks like you didn't complete the setup. Please make sure that you have completed the android-junit5 setup: https://github.com/mannodermaus/android-junit5#setup Applying the plugin is not enough according to their docs.

Note that their setup guide says apply the plugin to the app module, Paparazzi doesn't work in app modules yet, and you're applying to a library.

Also as far as I know that plugin is for instrumentation tests, is it necessary for running Jupiter tests in testDebugUnitTest?

If none of these help, can you please provide a small repro project?

jrodbx commented 1 year ago

Paparazzi currently doesn't support Junit 5. We're working on potentially supporting that after https://github.com/cashapp/paparazzi/issues/282 lands, which is slated for the 1.4 release.

timrijckaert commented 1 year ago

Thanks for now we have created a separate module to host our Paparazzi screenshot tests.

danielgomesoliveira commented 1 year ago

I was having the exact same issue when using this plugin, I managed to make it work without the need to have a different module by adding this 2 dependencies

testImplementation("junit:junit:4.13.2")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.9.3")
Yiran001 commented 1 year ago

I was stuck on this for some days now. Switching to Junit 4 helped. Maybe a hint or compatibility information should go into the readme

danielgomesoliveira commented 1 year ago

Maybe a hint would be nice to link the issue to this plugin so the devs avoid some debugging time, but not sure it's Paparazzi's responsibility to provide this. In the plugin setup link as referred by @TWiStErRob there are some optional dependencies that should be added to also to run junit4 tests (the case of Paparazzi).

TWiStErRob commented 1 year ago

I agree with @Yiran001: the fact that Paparazzi only supports JUnit 4 is only very implicitly "documented" by the fact that there's a transitive dependency and the fact that it's only provided entry point is a class extending TestRule. For a JVM testing library that only works with JUnit 4 (i.e. not TestNG, Jupiter, Spock, etc.), somehow this should be made clear in the README / website. On the other hand the whole world of Android is pretty much tightly coupled with JUnit 4 (AGP, Espresso, Robolectric to name a few), so this is sadly close to common sense. I'm glad to see some challengers of status quo though, Jupiter is awesome!