Anybody got an example of a Kotest test for a grad...
# kotest
s
Anybody got an example of a Kotest test for a gradle plugin in kotlin using GradleRunner that works? I'm trying for the first time, and getting this exception:
Copy code
Caused by: org.gradle.testkit.runner.InvalidPluginMetadataException: Test runtime classpath does not contain plugin metadata file 'plugin-under-test-metadata.properties'
   at org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading.readImplementationClasspath(PluginUnderTestMetadataReading.java:44)
   at org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading.readImplementationClasspath(PluginUnderTestMetadataReading.java:37)
   at org.gradle.testkit.runner.internal.DefaultGradleRunner.withPluginClasspath(DefaultGradleRunner.java:162)
    ...
I've seen old posts about people seeing this specific error, and this plugin is supposed to help with an issue in IDEA:
Copy code
"com.palantir.idea-test-fix" version "0.1.0"
but it doesn't help me. I didn't look into it so don't know what specifically this is doing. Anyway was hoping someone else has this working 🙂 Thanks in advance for any info. In case it's useful, here's the snippet causing the above error:
Copy code
val gradleRunner = GradleRunner.create()
        .withPluginClasspath()
        .withProjectDir(testProjectDir.root)
        .withTestKitDir(testProjectDir.newFolder())
s
Are you trying to test a gradle plugin itself
s
Yup, have one with a few tasks, and can debug loading it with a kotest no problem. But running a gradle build to actually test results of the tasks executed during a build requires the Gradle runner. Which is when I hit this thing...
s
It's a pretty niche use case, so not sure if anyone will have had experience in here with it.
It does look like the classpath isn't being set properly
s
Cool, was worth a shot...
s
how are you executing the tests, via the plugin or via the gradle window
s
Plugin so far. The nice thing about the Gradle runner test is it essentially sets up a test project on the fly. I'd have to set up a separate project using the plugin to run gradle tasks that way, takes a little work...
s
When I write my gradle plugin, I install to local, then have another project that uses that plugin from local.
Is that what this gradle runner thing is meant to save doing ?
s
Yeah, that's probably what I'll do tomorrow too...
Yup. It sets up a test on the fly then let's you run tasks from test code using the runner, and verify results
Part of the code you haven't seen him the test makes the test project and writes out a build.gradle with whatever the test needs
s
that's clever
There's probably some class path trickery that our plugin isn't doing right
s
Yeah the runner has that usePluginClasspath call to ensure the test gradle run can see the test classpath. Evidently that palantir plugin has some workaround for a bug/feature in IDEA that causes this error. Tomorrow I'm gonna dig into what it's trying to do and see if I can tell what's needed
👍🏻 1
m
Maybe it’ll help
s
Awesome, thanks I'll check it out. Are you using Idea? or Android Studio? or something else to run tests?
m
I mostly work with AS, but it should work with Idea as well. Or just from the console
s
Thanks. Did you ever see the 'plugin-under-test-metadata.properties' error? Or did it just work on yours?
m
I had some trouble but, I don’t remember any specifics. I set it up couple of months ago.
s
What JDK are you using?
m
At the time of writing I used 1.8 but now I’m on 14
s
Cool, I'm on 14 too so that's evidently not it 🙂 Thanks for your help!
m
Did you try to clone my project and run tests?
s
Not yet, still tinkering with setting up mine using yours as a template, but so far still get the same error. After I finish trying stuff I'll do that just to see if it's specific to my environment and not my project...
FWIW I found a post in StackOverflow for this problem, and their fix seems to work. I had to translate from groovy to kotlin, and ended up adding this to my build.gradle.kts. Michal, don't know why your project didn't need this, so still trying to figure this out.
Copy code
val fixIdeaPluginClasspath = tasks.create("fixIdeaPluginClasspath") {
    doFirst {
        tasks.pluginUnderTestMetadata.configure {
            val ideaClassesPath = project.buildDir.toPath()
                    .resolveSibling("out")
                    .resolve("production").toFile()
            val newClasspath = pluginClasspath.toMutableList()
            newClasspath.add(0, ideaClassesPath)
            pluginClasspath.setFrom(newClasspath)
        }
    }
}
tasks.getByName("pluginUnderTestMetadata").mustRunAfter(fixIdeaPluginClasspath)

fun org.gradle.plugins.ide.idea.model.IdeaProject.settings(block: ProjectSettings.() -> Unit) =
        (this@settings as ExtensionAware).extensions.configure(block)

fun ProjectSettings.taskTriggers(block: org.jetbrains.gradle.ext.TaskTriggersConfig.() -> Unit) =
        (this@taskTriggers as ExtensionAware).extensions.configure("taskTriggers", block)

idea {
    project {
        settings {
            taskTriggers {
                beforeBuild(fixIdeaPluginClasspath, tasks.pluginUnderTestMetadata)
            }
        }
    }
}
149 Views