Skill: Project Test Runner (Java + Gradle, macOS, JUnit 5 Only)
This skill defines what a “test” is and how tests are executed for this Java project. It is designed to be used together with a TDD skill that determines when tests must run.
Language: Java
Test framework: JUnit 5 (Jupiter)
Test runner: always ./gradlew test (macOS only)
Detailed test output: XML files under build/test-results/test/TEST-*.xml
1. Definition of a Test
A test in this project is:
- •A Java method annotated with
@org.junit.jupiter.api.Test - •Located in a test class under the directory
src/test/java - •Part of a test class following normal JUnit 5 structure
Examples of valid test locations (inline only):
- •
src/test/java/com/example/MyServiceTest.java - •
src/test/java/com/example/domain/OrderProcessorTest.java
A new behavior is defined by:
- •Adding a new
@Testmethod to an existing JUnit 5 test class, or - •Creating a new test class under
src/test/javathat contains one or more@Testmethods
JUnit 5 assertions (e.g., Assertions.assertEquals, assertThrows) should be used.
No Kotlin and no JUnit 4 are present in this project.
2. Running Tests (macOS only)
When the TDD skill instructs the agent to "run the tests", the agent must execute:
./gradlew test
This command must be run from the project root (the directory containing gradlew).
Gradle Daemon
Do not use the --no-daemon flag with Gradle commands unless specifically troubleshooting daemon issues. The Gradle daemon improves build performance by keeping the JVM warm between builds.
Avoid Clean Builds
Use ./gradlew build, not ./gradlew clean build. Gradle's incremental build correctly detects changes. Only use clean when:
- •Explicitly debugging build cache issues
- •User specifically requests it
Gradle Wrapper
When creating a standalone Gradle project, use the gradle wrapper command to generate wrapper files instead of copying them from another project:
cd new-project-directory gradle wrapper --gradle-version 8.11.1
This is cleaner than copying gradle/, gradlew, and gradlew.bat files and avoids permission issues.
Output Filtering
Do not use output filtering with Gradle commands (no | tail, | head, or 2>&1 redirection). Gradle's console output is already concise - just task names and pass/fail status. Verbose test output (Hibernate SQL, Spring Boot logs, etc.) is captured in TEST-*.xml files, not streamed to the console.
Test Verification Commands
- •Use
./gradlew checkto verify changes - this runs all test types (unit, integration, component tests) - •Use
./gradlew testonly when specifically running unit tests in a TDD loop - •
./gradlew testonly runs unit tests and misses integration/component tests - •NEVER just compile tests to verify they work - always run them
Definition of Done for Code Changes
For any code modification task (refactoring, bug fixes, new features):
- •Compilation passing is a prerequisite, not success
- •Success =
./gradlew buildpasses (includes all tests)
Test Coverage for Refactoring
When performing refactoring tasks (renaming classes, methods, moving files, changing signatures), always run the full test suite (./gradlew check) without excluding any test categories. Refactoring can break:
- •Integration tests that reference renamed classes in configuration
- •Component tests that verify service interactions
- •End-to-end tests that may have references to renamed elements
Only exclude test categories when explicitly instructed by the user or when debugging a specific test failure.
Exit code meaning:
- •Exit code 0 → all tests passed
- •Non-zero exit code → tests failed or tests could not run due to build errors
The console output of Gradle indicates only overall success or failure, not individual test results.
Build Success Is Authoritative
When ./gradlew build succeeds (BUILD SUCCESSFUL), that is authoritative proof that all tests passed. Do not:
- •Read TEST*.xml files to "verify" results
- •Parse build/reports for confirmation
- •Run additional commands to check test outcomes
TEST*.xml and HTML reports are for human debugging, not for Claude verification.
3. Detailed Test Results (XML)
Detailed per-test results are always located in:
build/test-results/test/TEST-*.xml
Each XML file corresponds to a test class and contains:
- •
<testsuite>metadata such as total tests and failures - •
<testcase classname="..." name="...">elements - •Optional
<failure>elements that contain the failure message and stack trace snippet
The agent must extract:
- •The first failing test class name
- •The failing test method name
- •The failure message text
- •A useful stack trace snippet if present
This information must be used to explain why tests failed and guide the next RED → GREEN change.
4. Evidence Integration (for the TDD skill)
The TDD skill uses an Evidence block with fields:
- •
tests: pass | fail | not-run - •
last_output: <text>
This Test Runner skill defines how to populate those fields.
When tests pass:
- •
tests: pass - •
last_outputshould mention that./gradlew testexited with code 0
When tests fail:
- •
tests: fail - •
last_outputshould mention that./gradlew testexited with a non-zero code - •The agent must parse XML files (from
build/test-results/test/) and describe the failing test(s)
When tests cannot run (environment error):
- •
tests: not-run - •
last_outputshould say that Gradle could not be executed - •The agent must enter the BLOCKED state (as defined by the TDD skill)
5. Rules for the Coding Agent
- •The agent must always run tests using exactly:
./gradlew test - •The agent must not guess test results from reading code
- •The agent must never claim tests passed without real
./gradlew testoutput - •The agent must parse XML under
build/test-results/testto identify failing tests - •If Gradle cannot be run, the agent must enter BLOCKED and request user-provided output
- •The agent must not move to GREEN, VERIFY, or COMPLETE without real evidence
6. Tests Are Sacred
NEVER delete or remove tests to make a build pass. If tests fail:
- •Investigate why they fail
- •Fix the underlying issue (missing dependencies, configuration, etc.)
- •If a test is genuinely obsolete, discuss with the user before removal
Deleting tests hides broken functionality and is never an acceptable solution.
7. Test Failure Investigation
NEVER ignore test failures. When tests fail:
- •STOP and investigate the cause before proceeding
- •Do NOT assume the cause based on error message alone (e.g., "TimeoutException means Kafka isn't running")
- •Do NOT dismiss failures as "infrastructure not running" without verification
- •Do NOT proceed with commits or other work until failures are understood and resolved
- •Check test infrastructure - many tests use testcontainers which auto-start dependencies
After Fixing a Failing Test
When a test fails (whether from pre-commit hook, CI, or manual run):
- •Fix the test or the code causing the failure
- •Run the specific failing test to verify the fix
- •Only after the test passes, proceed with staging and committing
Never assume a fix is correct without running the test to verify.
8. Summary
- •Tests are JUnit 5
@Testmethods in Java only - •Tests are executed exclusively via
./gradlew teston macOS - •Exit code indicates pass/fail at a high level
- •Detailed failures live in
build/test-results/test/TEST-*.xml - •The agent must never guess test results and must always rely on real output