Tests run through Gradle in CI and locally; knowing its knobs saves hours of debugging.
The java plugin adds a test task that compiles src/test/java and runs the tests. For JUnit 5 (Jupiter), add testImplementation("org.junit.jupiter:junit-jupiter:...") plus testRuntimeOnly("org.junit.platform:junit-platform-launcher") and tell Gradle to use the JUnit Platform: tasks.test { useJUnitPlatform() }. Gradle 8.x+ also offers testing { suites { ... } } with useJUnitJupiter() to declare this declaratively.
Running and filtering:
./gradlew testruns everything;--tests "com.acme.UserTest"or--tests "*Integration*"filters by class or method pattern.--rerun-tasksortest --rerunforces a rerun; otherwise Gradle skips tests whose inputs are unchanged (UP-TO-DATE).--fail-faststops after the first failure;--continueruns other tasks even if tests fail.
Results appear in build/reports/tests/test/index.html and XML in build/test-results/ for CI tools. By default Gradle shows only failures; configure testLogging { events("passed", "failed"); showStandardStreams = true } to see output.
Tests run in a separate JVM: set maxParallelForks to run classes in parallel, jvmArgs, systemProperty("env", "ci") and environment(...) to configure it. Use tags or separate source sets / test suites (integrationTest) to keep slow integration tests out of the fast loop.
Example
plugins { java }
repositories { mavenCentral() }
dependencies {
testImplementation(platform("org.junit:junit-bom:5.11.4"))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.test {
useJUnitPlatform { excludeTags("slow") }
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
systemProperty("app.env", "test")
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
}
}
// $ ./gradlew test --tests "com.acme.UserServiceTest" --fail-fast
// $ ./gradlew test --rerun
// report: build/reports/tests/test/index.htmlRemember
- useJUnitPlatform() enables JUnit 5
- --tests filters; --rerun forces re-execution of up-to-date tests
- Reports land in build/reports/tests and build/test-results
- maxParallelForks and tags speed up the test loop
Watch out for
- Wondering why tests 'didn't run': they were UP-TO-DATE because nothing changed.