Skip to content

Set the TestKit directory apart from TestKit coverage - #834

Merged
alexander-yevsyukov merged 2 commits into
masterfrom
claude/split-testkit-dir
Nov 3, 2026
Merged

alexander-yevsyukov merged 2 commits into
masterfrom
claude/split-testkit-dir

Conversation

@alexander-yevsyukov

@alexander-yevsyukov alexander-yevsyukov commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

What

This PR separates two concerns that #831 bundled together: collecting TestKit coverage, and choosing where TestKit builds keep their Gradle user home.

  • enableTestKitCoverage() deals with coverage only again. It passes the JaCoCo agent JAR and the exec directory to the test JVM, as it did before Share one TestKit directory among modules for TestKit coverage #831. The custom io.spine.tools.gradle.testkit.coverage.home property (TESTKIT_HOME_PROPERTY) is gone. It duplicated Gradle's own org.gradle.testkit.dir property, which GradleRunner.create() reads whenever a runner gets no explicit withTestKitDir(...). The withTestKitDir Javadoc documents that property for the test process.
  • A new Project.useSharedTestKitDir() in io/spine/gradle/testing/TestKitDir.kt sets org.gradle.testkit.dir to <Gradle user home>/caches/spine-testkit on every Test task of the project. It applies whether or not a task runs TestKit builds, and whether or not the module enables coverage.

Where it is applied, and why there

Every JVM module of the SDK repositories applies the module-testing script plugin. jvm-module, test-module, and each consumer's own module.gradle.kts apply it, and uber-jar-module gets it through module. That plugin already owns the test setup of a module (setupTests(), registerTestTasks(), forceTestDependencies()), so its project.run { ... } block now also calls useSharedTestKitDir(). kmp-module cannot apply module-testing, because the latter brings java-library. Instead, it mirrors that plugin's test setup for jvmTest, so it calls the function too.

The logic itself lives in io.spine.gradle.testing beside TestKitCoverage.kt and SpineCompilerCoverage.kt. Like them, it is a Project extension that configures tasks.withType<Test>().

Not a task input

The property is set from a doFirst action, as the two coverage helpers in the package do for their paths. The absolute path differs between machines (D:\a\.gradle\... on a Windows runner, /home/runner/.gradle/... on Linux). As a Test task input, it would only make the build-cache keys differ, because where TestKit builds keep their caches does not affect the test results. A Test task that already has the property, set by a module's own build script, keeps its value.

What the shared directory holds

A TestKit directory is the Gradle user home of the builds that GradleRunner runs. The local shared one holds mostly Gradle's instrumented copies of the JARs on the classpath of the plugin under test (caches/9.8.2/transforms, about 200 MB). It also holds the compiled build scripts of the test projects (caches/9.8.2/kotlin-dsl, about 36 MB). It holds no generated Gradle API JARs. Without the property, TestKit uses build/tmp/<task>/work/.gradle-test-kit, so every Test task of every module, every clean, and every fresh CI checkout starts empty. The directory stays under caches/, which gradle/actions/setup-gradle saves on the default branch (gradle-home-cache-includes: caches by default) and pull-request runs restore.

buildSrc's own tests are left alone

buildSrc's IgTests keep TestKit's default directory. No CI workflow of config runs them, so sharing it would only help local runs. That doesn't justify a second copy of the path in buildSrc/build.gradle.kts, which can't use buildSrc code.

Compatibility with plugin-testlib

  • Released plugin-testlib versions (up to the one on tool-base master) call withTestKitDir(<module>/build/testkit-home) explicitly when coverage is on. That call overrides the system property, so they are unaffected. TestKit tests that don't choose a directory now use the shared one.
  • None of them reads io.spine.tools.gradle.testkit.coverage.home. Only the original draft of Pass the TestKit coverage agent on the command line, move the shared TestKit directory tool-base#207 read it, so removing the property breaks nothing released.
  • The reworked Pass the TestKit coverage agent on the command line, move the shared TestKit directory tool-base#207 no longer chooses a TestKit directory. It only adds -Dorg.gradle.jvmargs=-javaagent:... to the runner's arguments. With this PR, its runners get the shared directory through org.gradle.testkit.dir. Without this PR, TestKit falls back to its default per-task directory, so it still works. This PR and Default GitHub token #207 can merge in either order.
  • BuildCacheSpec in tool-base points its test project at a build-cache folder inside that project, so a persistent shared Gradle home is safe for it.

Verification

  • ./gradlew :buildSrc:build detekt passes: 325 tests, 0 failures.
  • A throwaway fixture build that applies useSharedTestKitDir() to a plain java project with JUnit and gradleTestKit(), run with Gradle 9.8.2:
    • The test JVM sees org.gradle.testkit.dir=<Gradle user home>/caches/spine-testkit, and a GradleRunner build inside the test writes its caches/ there.
    • With --configuration-cache, the second run reuses the entry, and the doFirst still sets the property.
    • With a project-local build cache, cleanTest test under a different Gradle user home (so a different absolute path) gets :test FROM-CACHE. The path is not part of the cache key, and the doFirst action keeps Test tasks cacheable. As a control, the same fixture with systemProperty(...) set at configuration time re-executes :test under the second Gradle user home.
  • Reviewed with the gradle-review, kotlin-engineer, and review-docs reviewers. Their findings are addressed.

🤖 Generated with Claude Code

`enableTestKitCoverage()` no longer passes the custom
`io.spine.tools.gradle.testkit.coverage.home` property. It deals with the
JaCoCo agent and the exec directory only.

The new `useSharedTestKitDir()` sets Gradle's own `org.gradle.testkit.dir`
on every `Test` task, at execution time, pointing it at
`<Gradle user home>/caches/spine-testkit`. `module-testing` and `kmp-module`
apply it, so every module gets it, whether it collects TestKit coverage
or not. The tests of `buildSrc` itself use the same directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings November 3, 2026 19:16
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T19:41:23.151942Z 20ec3ff New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approved

There are no active review issues for the change separating shared TestKit directory configuration from coverage collection.

No open issues 🎉

What changed in this PR

This PR separates TestKit directory configuration from coverage collection in the shared Gradle build conventions, allowing tests to reuse caches independently of coverage settings.

Changes:

  • Adds useSharedTestKitDir() to configure Gradle’s standard TestKit directory property at execution time, preserving task-specific overrides.
  • Applies the shared directory to JVM and Kotlin Multiplatform test tasks, and separately to buildSrc tests.
  • Removes directory selection and the custom home property from enableTestKitCoverage().
File Description
buildSrc/​src/​main/​kotlin/​module-testing.gradle.kts Enables the shared TestKit directory for JVM module tests.
buildSrc/​src/​main/​kotlin/​kmp-module.gradle.kts Applies the same configuration to multiplatform JVM tests.
buildSrc/​src/​main/​kotlin/​io/​spine/​gradle/​testing/​TestKitDir.kt Defines the shared-directory helper and documents its behavior.
buildSrc/​src/​main/​kotlin/​io/​spine/​gradle/​testing/​TestKitCoverage.kt Limits the coverage helper to coverage-related configuration.
buildSrc/​build.gradle.kts Configures buildSrc tests to use the shared TestKit directory.

Review effort: Balanced

@alexander-yevsyukov alexander-yevsyukov self-assigned this Nov 3, 2026
@alexander-yevsyukov alexander-yevsyukov moved this to In Review in v2.0 Nov 3, 2026
Only local runs would gain from sharing it, as no CI workflow runs them.
That does not justify a second copy of the path to keep in sync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexander-yevsyukov
alexander-yevsyukov merged commit 3cc29d4 into master Nov 3, 2026
2 checks passed
@alexander-yevsyukov
alexander-yevsyukov deleted the claude/split-testkit-dir branch November 3, 2026 19:41
@github-project-automation github-project-automation Bot moved this from In Review to ✅ Done in v2.0 Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

2 participants