A team adds junit-jupiter-api and calls useJUnitPlatform(), but the build reports zero tests run. What is the most likely cause and the fix?
answer
- API compiles, engine runs
- 0 tests = missing engine
- BUILD SUCCESSFUL but nothing ran
- add engine or aggregator
- check testRuntimeClasspath
basics
~10 sThey added only the API, not the engine. Without junit-jupiter-engine on testRuntimeOnly the Platform has nothing to discover the tests. Add the engine (or the junit-jupiter aggregator) and the tests run.
solid answer
~40 sThe classic symptom of 'compiles fine, zero tests run' is a **missing runtime engine**. `junit-jupiter-api` lets test code compile against `@Test` and `Assertions`, and `useJUnitPlatform()` tells Gradle to use the Platform — but the Platform discovers tests by asking registered `TestEngine`s, and the only thing that registers the Jupiter engine is `junit-jupiter-engine` on the **runtime** classpath. With just the API present, the launcher finds no engine, discovers no tests, and Gradle happily reports BUILD SUCCESSFUL with 0 tests. The fix is to add `testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")`, or simpler, replace the API dependency with the aggregator `testImplementation("org.junit.jupiter:junit-jupiter")` which brings the engine too. On newer Gradle, also ensure `junit-platform-launcher` is on `testRuntimeOnly`.
code
kotlin · 5 linesdependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") // the missing piece
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}go deeper
Recognize 'compiles but 0 tests' means the engine is missing; add it.
Explain the compile-API/runtime-engine split and how to verify via the dependencies report.
List the full diagnosis checklist including launcher, source set, tag filters, and wrong @Test import.
Add a CI guard that fails the build when test count is zero so this silent failure can never ship.
## The trap: compile vs runtime JUnit 5 cleanly separates what you **compile against** (the API) from what **runs your tests** (the engine). It is entirely possible to have a project that: - compiles all test classes (API present), - has `useJUnitPlatform()` set, - yet runs **zero tests**. That is because discovery is delegated to `TestEngine`s found via ServiceLoader at runtime, and no engine is on the classpath. ## Diagnosis checklist 1. Is `junit-jupiter-engine` (or the `junit-jupiter` aggregator) on `testRuntimeOnly` / `testImplementation`? If only `-api` is declared, that is the bug. 2. Is `junit-platform-launcher` present (required on recent Gradle)? 3. Run `./gradlew test --info` — it will show the worker starting but no tests discovered. 4. Run `./gradlew dependencies --configuration testRuntimeClasspath` and grep for `junit-jupiter-engine`. ## The fix ```kotlin dependencies { // Either the explicit pair: testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher") // Or simply the aggregator (covers the engine): // testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") } tasks.test { useJUnitPlatform() } ``` ## Bonus failure modes - Tests in the wrong source set (not `src/test/java` or `src/test/kotlin`). - A `filter`/`includeTags` that excludes everything. - Importing `org.junit.Test` (JUnit 4) instead of `org.junit.jupiter.api.Test` — the Jupiter engine then ignores them.
- How would you confirm the engine is missing from the classpath?Run ./gradlew dependencies --configuration testRuntimeClasspath and look for junit-jupiter-engine. Its absence confirms the diagnosis.
- Could importing org.junit.Test cause the same zero-tests symptom?Yes — that is the JUnit 4 annotation. The Jupiter engine only discovers org.junit.jupiter.api.Test, so JUnit 4 imports are ignored unless the Vintage engine is present.
saying these in an interview costs you the question
- Concluding the build is fine because it says BUILD SUCCESSFUL with 0 tests.
- Adding more API artifacts instead of the runtime engine.