A JUnit test can be written correctly and still fail to run when Gradle or the IDE cannot discover it. This often results in the “No Tests Found for Given Includes” error, which means the test runner could not match the requested class, method, or filter to a valid test.
In many cases, the problem is not in the test logic. It comes from how the test is configured or discovered. An incorrect @Test import, missing useJUnitPlatform() configuration, incompatible JUnit dependencies, outdated test filters, or an unexpected folder structure can all prevent the runner from finding the test.
The fastest way to resolve the error is to check the discovery setup before debugging the test itself. By the end of this guide, you will understand where test discovery commonly fails and how to fix each issue without changing working test code unnecessarily.
What is the “No Tests Found for Given Includes” Error?
The “No Tests Found for Given Includes” error appears when Gradle or your IDE tries to run a specific test but cannot find any test that matches the requested class, method, or filter.
For example, you may select a test method in IntelliJ IDEA, run a filtered Gradle command, or execute a test task configured with an include pattern. If the runner cannot map that request to a recognized test, the task fails before the test method is executed.
This does not always mean that the test class is missing. The file may exist and compile correctly, but JUnit may not recognise it as a test. An incorrect annotation import, missing JUnit Platform configuration, incompatible dependencies, or an incorrect source directory can all break test discovery.
What are the common causes of “No Tests Found for Given Includes” Error?
Multiple issues can lead to the “No Tests Found for Given Includes” error. Some of the common issues are:
1. Missing or Improper Configuration in build.gradle
Gradle needs both the correct JUnit dependencies and the appropriate test task configuration to discover and run tests. A project may compile successfully but still report that no tests were found if the required test engine is missing or the JUnit Platform has not been enabled.
For JUnit 5, the test task should use the JUnit Platform:
test {
useJUnitPlatform()
}Output –
Without useJUnitPlatform(), the Gradle test task will not use the JUnit Platform to discover and execute JUnit Jupiter tests. You also need a runtime engine, such as junit-jupiter-engine, because the API dependency alone lets you write and compile tests but does not execute them.
The same issue can occur when custom include patterns are too restrictive. For example, a pattern that only includes classes ending in Test will exclude a class named LoginTests unless that pattern is also configured.
2. Incorrect Import of @Test Annotation
In JUnit-based projects, the @Test annotation marks a method as a test. However, if the incorrect annotation is imported from a different library, such as JUnit 4 instead of JUnit 5, this can lead to conflicts and the error message “No Tests Found for Given Includes”.
Also Read: TestNG Annotations in Selenium Webdriver
3. Framework Version or Compatibility Mismatch
Test discovery can fail when the project contains dependencies from different JUnit generations without the engines required to support them. This commonly happens during a gradual migration from JUnit 4 to JUnit 5.
JUnit 5 separates the API used to write tests from the engine used to execute them. A project may therefore compile JUnit 5 tests with junit-jupiter-api but fail to run them when junit-jupiter-engine is missing at runtime.
A similar problem occurs when JUnit 4 tests remain in the project after Gradle has been configured to use the JUnit Platform. Those tests require the Vintage engine unless they are migrated to JUnit Jupiter.
Version inconsistencies can also create discovery problems. For example, declaring different versions of the Jupiter API and engine may allow compilation but produce unexpected behavior during execution. Using a single JUnit version or the JUnit Bill of Materials helps keep related modules aligned.
When checking for a compatibility issue, review the full resolved dependency tree rather than only the dependencies written in build.gradle. Another library may be introducing an older JUnit version transitively.
4. Issues with Gradle Test Execution
Even when the JUnit dependencies are correct, Gradle may fail to find a test because of how the test task is invoked. This often happens when an IDE or command-line instruction applies a filter that no longer matches the compiled test class.
For example, the following command asks Gradle to run one specific test class:
./gradlew test --tests "com.example.LoginTest"
Output –
Gradle returns the error if the class was renamed, moved to another package, assigned to a different module, or excluded from the selected test task. The same issue can occur when IntelliJ IDEA keeps an outdated run configuration after you rename a class or test method.
Custom filters in build.gradle can also remove tests from execution:
test {
include '**/*UnitTest.class'
}Output –
With this configuration, a class named LoginTest will not run because it does not match the *UnitTest pattern. Gradle applies configured include and exclude patterns before executing the discovered tests.
In multi-module projects, you must also run the task that belongs to the module containing the test. Running the root test task or another module’s task may produce no match for a test that exists elsewhere. Custom Test tasks require the correct compiled test directories and runtime classpath as well.
To isolate an execution issue, first run the complete test task without a class or method filter:
./gradlew test
Output –
If the full suite runs but the filtered command fails, the problem is likely the test name, package path, selected module, or saved IDE configuration rather than the JUnit setup.
5. Misaligned Folder Structure Between Test and Source Directories
Gradle only compiles and scans the directories configured as test sources. In a standard Java project, production code belongs under src/main/java, while test classes belong under src/test/java.
A typical structure looks like this:
If LoginServiceTest.java is placed under src/main/java, a custom folder, or the wrong module, Gradle may not include it in the test source set. The class may still appear in the IDE, but it will not be available to the test task.
Folder and package mismatches can also cause problems when you run a test by its fully qualified class name. For example, this command expects the class to use the com.example package:
./gradlew test --tests "com.example.LoginServiceTest"
Output –
If the class was moved but its package declaration or run configuration was not updated, the filter will not match the compiled test.
When a project intentionally stores tests in a custom directory, add that location to the Gradle source set:
sourceSets {
test {
java {
srcDirs = ['src/test/java', 'src/integrationTest/java']
}
}
}Output –
In multi-module projects, also confirm that the test is located in the module whose test task you are running. A correctly structured test inside one module will not be discovered by another module’s test task.
Before changing the test code, verify the file location, package declaration, selected Gradle module, and configured test source directories. If any of these point to different locations, Gradle may report that no matching tests were found.
How to Solve the “No Tests Found for Given Includes” Error?
Here are some of the steps to solve the “No Tests Found for Given Includes” error:
1. Update and Complete the build.gradle Configuration
Gradle needs the correct JUnit dependencies and test task configuration to discover and run your tests. For a JUnit 5 project, use a setup like this:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.14.4')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}Output –
The JUnit BOM keeps the Platform and Jupiter dependencies on compatible versions. The junit-jupiter dependency provides the API and engine for JUnit 5 tests, while junit-platform-launcher supplies the launcher used during test execution. The useJUnitPlatform() setting tells Gradle to discover and run tests through the JUnit Platform.
After updating the file, refresh the Gradle project in your IDE and run:
./gradlew clean test
Output –
The clean task removes old compiled files that may still refer to renamed or moved tests. If the full test task runs successfully but a filtered command still fails, check the class name, method name, package, or –tests filter instead.
2. Ensure the Correct Library is Used for @Test Annotation Import
Do check that the @Test annotation is imported from the correct JUnit version, so as to avoid any kind of error.
For JUnit 5, import it from:
import org.junit.jupiter.api.Test;
For JUnit 4, import it from:
import org.junit.Test;
3. Use a JUnit 5 -Compatible Library for Better Integration
While using JUnit 5, it’s important to ensure that all the libraries are compatible. Using JUnit 5 libraries will enhance the integration with modern tools and eliminate conflicts with legacy versions.
4. Include the JUnit 5 Vintage Engine for Legacy Support
If your project uses JUnit 5 but still contains tests written with JUnit 4, enabling useJUnitPlatform() alone may not be enough. The JUnit Platform needs the Vintage engine to discover and execute those older tests.
Add the Vintage engine alongside your JUnit 5 dependency:
dependencies {
testImplementation platform('org.junit:junit-bom:5.14.4')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'junit:junit:4.13.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}Output –
This allows existing JUnit 4 tests that import org.junit.Test to run on the JUnit Platform alongside tests that use org.junit.jupiter.api.Test. Use Vintage only as a migration bridge. The engine is deprecated in JUnit 6, so new tests should use JUnit Jupiter while legacy tests are migrated gradually.
5. Compare IntelliJ IDEA and Gradle Test Execution
Once the required test engines are configured, run the affected test through IntelliJ IDEA and then through Gradle. Comparing the results helps you determine whether discovery is failing in the IDE configuration, the Gradle task, or both.
This step helps you separate a Gradle filtering problem from a broader test discovery issue. If the test runs through IntelliJ IDEA but fails with a command such as:
./gradlew test --tests "com.example.LoginServiceTest"
Output –
The likely cause is an incorrect Gradle filter, package name, module, or saved run configuration. If neither IntelliJ IDEA nor Gradle detects the test, return to the annotation imports, dependencies, and source directory setup.
For results that match command-line and CI execution more closely, open Settings > Build, Execution, Deployment > Build Tools > Gradle and set Run tests using to Gradle.
6. Align the Hierarchies of Your Test and Source Directories
If the test engines and runner settings are correct, confirm that Gradle is compiling the test file as part of the test source set. In a standard Java project, application code belongs under src/main/java, while test classes belong under src/test/java.
For example:
project-root/ ├── src/ │ ├── main/ │ │ └── java/ │ │ └── com/example/ │ │ └── LoginService.java │ └── test/ │ └── java/ │ └── com/example/ │ └── LoginServiceTest.java └── build.gradle
The directory path should also agree with the package declared in the test:
package com.example;
If your tests use a custom directory, either move them under src/test/java or register the directory in build.gradle:
sourceSets {
test {
java.srcDir 'tests'
}
}Output –
After correcting the structure, refresh the Gradle project and run ./gradlew clean test. This ensures Gradle recompiles the tests from their updated locations instead of using older build output.
Best Practices to Follow to Avoid the “No Tests Found for Given Includes” Error
Once test discovery is working, the next step is to keep it stable as the suite grows. The most useful practices focus on reducing brittle filters, keeping execution consistent, and detecting discovery problems before they block a developer or CI job.
1. Prefer Tags Over File-Name Filters
Avoid relying on narrow include patterns such as **/*UnitTest.class unless the naming rule is enforced across the project. A single renamed class can fall outside the pattern without any problem in the test code itself.
For JUnit 5, tags provide a clearer way to group tests:
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("integration")
class PaymentIntegrationTest {
@Test
void processesPayment() {
// Test logic
}
}You can then select the group in Gradle:
test {
useJUnitPlatform {
includeTags 'integration'
}
}Output –
Tags describe the purpose of a test without tying discovery to a class-name suffix. However, includeTags ‘integration’ makes the task run only tests carrying that tag. Apply the filter only when that restricted selection is intentional, or the task may be left with no matching tests.
2. Use the Same Test Runner Locally and in CI
A test may run in the IDE but fail in CI when the two environments use different runners or Gradle versions. Configure IntelliJ IDEA to delegate test execution to Gradle when your build pipeline also uses Gradle.
This gives developers feedback that is closer to the final CI result. It also exposes missing dependencies, custom task settings, and source-set problems earlier.
Use the Gradle Wrapper for local and CI execution:
./gradlew test
Output –
The wrapper ensures that both environments use the Gradle version defined by the project instead of whichever version is installed on the machine.
3. Keep Filtered Commands Easy to Regenerate
Saved IDE configurations and CI commands often contain full class or method names. These filters become stale when a test is renamed, moved to another package, or converted into a parameterized test.
Avoid treating highly specific run configurations as permanent project configuration. Regenerate them after refactoring and review any checked-in CI filters when test packages change.
For routine validation, run the complete task first:
./gradlew test
Output –
Use –tests filters mainly for targeted debugging or controlled test selection.
4. Validate Test Discovery Before Splitting the Suite
Large pipelines often divide tests by module, class pattern, tag, or custom Gradle task. Before adding those filters, confirm that the unfiltered task discovers the expected tests.
For example, run the complete unit test task before configuring separate shards or groups. If the base task finds 500 tests but the filtered jobs collectively run only 430, the missing tests may be excluded by overlapping or incomplete filters.
Tracking the test count in CI can also reveal sudden discovery changes after a package rename, dependency upgrade, or source-set update.
5. Review Dependency Resolution After Framework Upgrades
Updating a JUnit version in build.gradle does not guarantee that Gradle resolves the version you expect. Plugins and third-party libraries can introduce older JUnit components through transitive dependencies.
After a framework upgrade, inspect the resolved test dependencies:
./gradlew dependencies --configuration testRuntimeClasspath
For a specific module, use dependencyInsight:
./gradlew dependencyInsight \ --dependency junit-jupiter-engine \ --configuration testRuntimeClasspath
Output –
This helps you catch version conflicts before they appear as missing tests or inconsistent behavior across machines. Using a JUnit BOM or central version catalogue can also keep related modules aligned.
Conclusion
Treat the “No Tests Found for Given Includes” error as a discovery issue first. Run the full Gradle test task without filters. If tests run, correct the class, method, package, module, or saved run configuration. If they do not, verify the JUnit engine, useJUnitPlatform(), annotation imports, and test source directories.
Once the issue is fixed, reduce the chance of it returning by using the Gradle Wrapper, keeping IDE and CI execution aligned, and reviewing test filters after package or class changes. These checks make test discovery more predictable as the suite grows.















