Running tests

Gradle · Essentials · 8 min

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 test runs everything; --tests "com.acme.UserTest" or --tests "*Integration*" filters by class or method pattern.
  • --rerun-tasks or test --rerun forces a rerun; otherwise Gradle skips tests whose inputs are unchanged (UP-TO-DATE).
  • --fail-fast stops after the first failure; --continue runs 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.html

Remember

  • 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.

Check yourself

  1. You run ./gradlew test twice without changes. What happens the second time?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gradle.org/current/userguide/java_testing.html

Builds on

Unlocks

Nothing builds on this yet.