skip to content

How does withPluginClasspath() make the plugin under test available to the build, and how do you set it up?

level: middleimportance: must knowfreq 55%

answer

  1. plugin-under-test-metadata.properties
  2. java-gradle-plugin auto-wires it
  3. gradlePlugin { plugins { } } block
  4. no publish needed for plugins { id }
  5. explicit withPluginClasspath(files) variant

basics

~10 s

withPluginClasspath() injects the plugin-under-test's classes onto the build's classpath so plugins { id("...") } resolves without publishing. The java-gradle-plugin plugin generates this classpath automatically.

solid answer

~40 s

`GradleRunner.withPluginClasspath()` adds the plugin-under-test (its compiled classes and resources) to the build's plugin classpath, so a test project can apply it by id via the `plugins {}` block **without** publishing to a repository. The classpath comes from a generated metadata file. The clean way to wire it is the **`java-gradle-plugin`** plugin: declaring your plugin in the `gradlePlugin { plugins { ... } }` block makes it generate the plugin descriptor and a `plugin-under-test-metadata.properties` file, and add a `pluginUnderTestMetadata` task plus the TestKit dependency. Then `withPluginClasspath()` (no args) auto-discovers that metadata. If you manage the classpath yourself you can pass it explicitly: `withPluginClasspath(files)`. Without this, the `plugins { id(...) }` block in the test build fails to resolve the plugin.

code

kotlin · 19 lines
kotlin
plugins {
    `java-gradle-plugin`
}

gradlePlugin {
    plugins {
        create("greeting") {
            id = "com.example.greeting"
            implementationClass = "com.example.GreetingPlugin"
        }
    }
}

// In the test:
GradleRunner.create()
    .withProjectDir(testProjectDir)
    .withArguments("greet")
    .withPluginClasspath()   // auto-discovers plugin-under-test-metadata.properties
    .build()

go deeper

for a junior

Know it makes the plugin resolvable in the test build without publishing.

for a middle

Explain the metadata file and the java-gradle-plugin auto-wiring; recognize the not-found error.

for a senior

Discuss explicit classpath control, stale-metadata pitfalls, and recompilation ordering of tasks.

for a principal

Reason about classpath isolation between plugin runtime deps and test deps across a multi-plugin build.

## The problem it solves A functional test build script usually applies your plugin the production way: ```kotlin plugins { id("com.example.greeting") } ``` But the plugin hasn't been published anywhere the test build can resolve. `withPluginClasspath()` bridges that gap by injecting the plugin's classes directly onto the build's *plugin* classpath and registering its id, so resolution succeeds. ## How the classpath is discovered TestKit reads a generated file, `plugin-under-test-metadata.properties`, which lists the classpath entries (the plugin's `build/classes`, `build/resources`, and runtime dependencies). The no-arg `withPluginClasspath()` loads exactly that file. ## The easy path: java-gradle-plugin Applying the `java-gradle-plugin` plugin and declaring the plugin makes Gradle do the wiring for you: ```kotlin plugins { `java-gradle-plugin` } gradlePlugin { plugins { create("greeting") { id = "com.example.greeting" implementationClass = "com.example.GreetingPlugin" } } } ``` This automatically: - adds the `gradleTestKit()` dependency to the test classpath, - registers the `pluginUnderTestMetadata` task that writes `plugin-under-test-metadata.properties`, - makes the no-arg `withPluginClasspath()` work, - generates the plugin descriptor so the id is recognized. ## Explicit classpath If you are not using `java-gradle-plugin`, supply the classpath yourself: ```kotlin GradleRunner.create() .withPluginClasspath(listOf(File("build/classes/kotlin/main"), ...)) ``` ## Common failure If you forget `withPluginClasspath()` (or the metadata file is stale because the plugin wasn't recompiled), the test fails with a *Plugin with id '...' not found* error — that is the canonical symptom.

  • What error do you get if you forget withPluginClasspath()?
    The test build fails resolving the plugin: "Plugin with id '...' not found", because the plugin's classes were never put on the build's plugin classpath.
  • Where does the no-arg withPluginClasspath() get its entries?
    From the generated `plugin-under-test-metadata.properties` file, produced by the `pluginUnderTestMetadata` task that the `java-gradle-plugin` plugin registers.

saying these in an interview costs you the question

  • Saying you must publish the plugin to a local repo before functional testing.
  • Thinking withPluginClasspath() adds dependencies for the application code rather than the plugin classpath.
  • Forgetting that java-gradle-plugin auto-adds the TestKit dependency and metadata task.

context