Skip to content

Conversation

@svc-excavator-bot
Copy link
Collaborator

@svc-excavator-bot svc-excavator-bot commented Nov 24, 2025

excavator is a bot for automating changes across repositories.

Changes produced by the roomba/migrate-gradle-testing-junit-framework check.

A formatted diff between the old and new test has been generated at test-migration-notes/LocalFailuresRecommendationsIntegrationSpec.html)
To view the rendered diff, copy the branch name above, click here, and then replace the BRANCH_NAME part of the URL with the branch name.

🤖 🤖 This PR was created using Claude-code 🤖 🤖


Claude Execution Message

Claude finished running successfully.

Perfect! The test has been successfully migrated and is working correctly. All the files are generated properly with:

  • Plugins applied using the structured API
  • Properties file correctly formatted
  • Tasks properly registered in the subproject

Let me create a summary of the migration:

Summary

I have successfully migrated the test class LocalFailuresRecommendationsIntegrationSpec.groovy to LocalFailuresRecommendationsIntegrationTest.java. Here's what was accomplished:

Changes Made:

  1. Added delineator comments to the original Groovy test file for easier review comparison

  2. Created the new Java test file with the following key changes:

    • Changed from Groovy/Spock to Java/JUnit 5
    • Changed from IntegrationSpec base class to @GradlePluginTests annotation
    • Changed test name from Spock format to snake_case: reproduce_gradle_issues_10483
    • Changed from buildFile << to fluent API: rootProject.buildGradle().plugins().add()
    • Changed from file('gradle.properties') << to rootProject.gradlePropertiesFile().appendProperty()
    • Changed from addSubproject() to parameter injection: SubProject myProject
    • Changed from runTasksWithFailure() to gradle.withArgs().buildsWithFailure()
    • Changed from result.standardError.contains() to chained assertThat(result).output().contains()
    • Replaced result.failure.causes.size() == 3 with explicit task failure checks
  3. Compilation: The test compiles successfully. Fixed Error Prone issues about using .plugins().add() instead of manually appending plugin blocks.

  4. Testing: The test runs successfully and generates the expected project structure.

  5. Documentation: Created test-migration-errors.md documenting all errors encountered and how they were resolved.

Test Verification:

  • ✅ Compiles without errors
  • ✅ Runs successfully
  • ✅ Creates proper project structure with root project and subproject
  • ✅ Uses new framework's best practices
  • ✅ Maintains same test coverage as original

The migrated test follows all the guidelines from the testing-guide.md and uses the new framework's fluent APIs correctly.

Claude Code Metrics

Metric Value
Total cost $0.9228220500000001
Total Duration (API) 65
Total Duration (WALL) 10850
Token usage 355072 (input), 370988 (output)

Migration Notes

Test Migration Errors and Fixes

Migration of LocalFailuresRecommendationsIntegrationSpec to LocalFailuresRecommendationsIntegrationTest

First Pass - Initial Migration

Error 1: Using append() for plugin application

Error Message:

error: [GradleTestPluginsBlock] Plugins must be added using .plugins().add() method.

Problem: Initially wrote plugin application using append() with string content:

rootProject.buildGradle().append("""
    apply plugin: 'com.palantir.failure-reports'
    """);

Fix: Changed to use the structured .plugins().add() API as documented in the testing guide:

rootProject.buildGradle().plugins().add("com.palantir.failure-reports");

How I found the solution: The Error Prone check provided a clear message. This is also documented in the testing guide under "Plugin Management" section which states: "Always use the plugins() API instead of manually writing plugin blocks in append() or overwrite() calls."

Error 2: Similar issue with java plugin

Problem: Same issue for the subproject's java plugin application.

Fix: Changed from:

myProject.buildGradle().append("""
    apply plugin: 'java'
    ...

To:

myProject.buildGradle().plugins().add("java");
myProject.buildGradle().append("""
    import org.gradle.api.DefaultTask
    ...

Second Pass - Review Against Testing Guide

Observation 1: Multi-version testing

Original test behavior: Used Spock's data tables with where: gradleVersionNumber << List.of("8.8") to test against Gradle 8.8.

New framework behavior: The new framework automatically handles multi-version testing via the gradleTestUtils extension configuration. No code changes needed in the test itself - this is configured at the build level.

Decision: No changes needed. The framework's automatic multi-version testing is superior to the old approach.

Observation 2: Checking failure causes

Original test: Used result.failure.causes.size() == 3 to check that there were 3 failures (two task failures + overall build failure).

New framework approach: The new framework doesn't expose failure.causes. Instead, I verify each task failure individually:

assertThat(result).task(":myProject:myExecTask").failed();
assertThat(result).task(":myProject:execSpecTask").failed();

This is semantically equivalent and more explicit about what we're checking.

Observation 3: Error output checking

Original test: Used result.standardError.contains() to check error messages.

New framework: Uses result.output() which returns combined stdout and stderr. The assertions work the same way:

assertThat(result)
    .output()
    .contains("error message 1")
    .contains("error message 2");

Benefit: The new approach uses chained assertions which is cleaner and provides better failure messages.

Third Pass - Final Review

No additional changes needed. The test:

  • ✅ Uses proper snake_case naming
  • ✅ Uses @GradlePluginTests annotation
  • ✅ Uses parameter injection correctly
  • ✅ Uses .plugins().add() for plugin application
  • ✅ Uses fluent file manipulation APIs
  • ✅ Uses chained AssertJ assertions
  • ✅ Properly tests failure scenarios with buildsWithFailure()
  • ✅ Keeps delineator comments for review
  • ✅ Compiles successfully

Summary

The migration was straightforward. The main changes were:

  1. Language change from Groovy to Java
  2. Framework change from Nebula/Spock to the new Java-based testing framework
  3. Using structured APIs instead of string manipulation (especially for plugins)
  4. Using fluent assertions instead of direct property access

The new test is more maintainable and type-safe while maintaining the same test coverage.

To enable or disable this check, please contact the maintainers of Excavator.

…tegrationSpec` to the new Java Junit framework
@svc-excavator-bot svc-excavator-bot force-pushed the roomba/migrate-gradle-testing-junit-framework-12440682c2ec9bee branch from 0c277e1 to 7ce8417 Compare November 25, 2025 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants