Maven does not find JUnit tests to run
I have a maven program, it compiles fine. When I run mvn test
it does not run any tests (under TESTs header says There are no tests to run.
).
I've recreated this problem with a super simple setup which I will include below as well as the output when run with -X
.
The unit tests run fine from eclipse (both with its default junit package and when I instead include the junit.jar downloaded by maven). Also mvn test-compile
correctly creates the class under test-classes. I am running this on OSX 10.6.7 with Maven 3.0.2 and java 1.6.0_24.
Here is the directory structure:
/my_program/pom.xml
/my_program/src/main/java/ClassUnderTest.java
/my_program/src/test/java/ClassUnderTestTests.java
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my_group</groupId>
<artifactId>my_program</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>My Program</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencie开发者_如何学Cs>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
ClassUnderTest.java:
public class ClassUnderTest {
public int functionUnderTest(int n) {
return n;
}
}
ClassUnderTestTests.java:
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ClassUnderTestTests {
private ClassUnderTest o;
@Before
public void setUp() {
o = new ClassUnderTest();
}
@Test
public void testFunctionUnderTest_testCase1() {
Assert.assertEquals(1, o.functionUnderTest(1));
}
@Test
public void testFunctionUnderTest_testCase2() {
Assert.assertEquals(2, o.functionUnderTest(2));
}
}
End of mvn -X test:
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-surefire-plugin:2.7.1:test from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-surefire-plugin:2.7.1, parent: sun.misc.Launcher$AppClassLoader@5224ee]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.7.1:test' with basic configurator -->
[DEBUG] (s) basedir = /Users/aaron/Programs/my_program
[DEBUG] (s) childDelegation = false
[DEBUG] (s) classesDirectory = /Users/aaron/Programs/my_program/target/classes
[DEBUG] (s) disableXmlReport = false
[DEBUG] (s) enableAssertions = true
[DEBUG] (s) forkMode = once
[DEBUG] (s) junitArtifactName = junit:junit
[DEBUG] (s) localRepository = id: local
url: file:///Users/aaron/.m2/repository/
layout: none
[DEBUG] (f) parallelMavenExecution = false
[DEBUG] (s) pluginArtifactMap = {org.apache.maven.plugins:maven-surefire-plugin=org.apache.maven.plugins:maven-surefire-plugin:maven-plugin:2.7.1:, org.apache.maven.surefire:surefire-booter=org.apache.maven.surefire:surefire-booter:jar:2.7.1:compile, org.apache.maven.surefire:surefire-api=org.apache.maven.surefire:surefire-api:jar:2.7.1:compile, org.apache.maven.surefire:maven-surefire-common=org.apache.maven.surefire:maven-surefire-common:jar:2.7.1:compile, org.apache.maven.shared:maven-common-artifact-filters=org.apache.maven.shared:maven-common-artifact-filters:jar:1.3:compile, org.codehaus.plexus:plexus-utils=org.codehaus.plexus:plexus-utils:jar:2.0.5:compile, junit:junit=junit:junit:jar:3.8.1:compile, org.apache.maven.reporting:maven-reporting-api=org.apache.maven.reporting:maven-reporting-api:jar:2.0.9:compile}
[DEBUG] (s) printSummary = true
[DEBUG] (s) project = MavenProject: my_group:my_program:1.0-SNAPSHOT @ /Users/aaron/Programs/my_program/pom.xml
[DEBUG] (s) projectArtifactMap = {junit:junit=junit:junit:jar:4.8.1:test}
[DEBUG] (s) redirectTestOutputToFile = false
[DEBUG] (s) remoteRepositories = [ id: central
url: http://repo1.maven.org/maven2
layout: default
snapshots: [enabled => false, update => daily]
releases: [enabled => true, update => never]
]
[DEBUG] (s) reportFormat = brief
[DEBUG] (s) reportsDirectory = /Users/aaron/Programs/my_program/target/surefire-reports
[DEBUG] (s) session = org.apache.maven.execution.MavenSession@dfbb43
[DEBUG] (s) skip = false
[DEBUG] (s) skipTests = false
[DEBUG] (s) testClassesDirectory = /Users/aaron/Programs/my_program/target/test-classes
[DEBUG] (s) testFailureIgnore = false
[DEBUG] (s) testNGArtifactName = org.testng:testng
[DEBUG] (s) testSourceDirectory = /Users/aaron/Programs/my_program/src/test/java
[DEBUG] (s) trimStackTrace = true
[DEBUG] (s) useFile = true
[DEBUG] (s) useManifestOnlyJar = true
[DEBUG] (s) workingDirectory = /Users/aaron/Programs/my_program
[DEBUG] -- end configuration --
[INFO] Surefire report directory: /Users/aaron/Programs/my_program/target/surefire-reports
[DEBUG] Setting system property [user.dir]=[/Users/aaron/Programs/my_program]
[DEBUG] Setting system property [localRepository]=[/Users/aaron/.m2/repository]
[DEBUG] Setting system property [basedir]=[/Users/aaron/Programs/my_program]
[DEBUG] Using JVM: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10 for /Users/aaron/.m2/repository
[DEBUG] dummy:dummy:jar:1.0 (selected for null)
[DEBUG] org.apache.maven.surefire:surefire-booter:jar:2.7.1:compile (selected for compile)
[DEBUG] org.apache.maven.surefire:surefire-api:jar:2.7.1:compile (selected for compile)
[DEBUG] Adding to surefire booter test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-booter/2.7.1/surefire-booter-2.7.1.jar Scope: compile
[DEBUG] Adding to surefire booter test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-api/2.7.1/surefire-api-2.7.1.jar Scope: compile
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10 for /Users/aaron/.m2/repository
[DEBUG] dummy:dummy:jar:1.0 (selected for null)
[DEBUG] org.apache.maven.surefire:surefire-junit4:jar:2.7.1:test (selected for test)
[DEBUG] org.apache.maven.surefire:surefire-api:jar:2.7.1:test (selected for test)
[DEBUG] Adding to surefire test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-junit4/2.7.1/surefire-junit4-2.7.1.jar Scope: test
[DEBUG] Adding to surefire test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-api/2.7.1/surefire-api-2.7.1.jar Scope: test
[DEBUG] Test Classpath :
[DEBUG] /Users/aaron/Programs/my_program/target/test-classes
[DEBUG] /Users/aaron/Programs/my_program/target/classes
[DEBUG] /Users/aaron/.m2/repository/junit/junit/4.8.1/junit-4.8.1.jar
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10 for /Users/aaron/.m2/repository
[DEBUG] dummy:dummy:jar:1.0 (selected for null)
[DEBUG] org.apache.maven.surefire:surefire-booter:jar:2.7.1:compile (selected for compile)
[DEBUG] org.apache.maven.surefire:surefire-api:jar:2.7.1:compile (selected for compile)
[DEBUG] Adding to surefire booter test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-booter/2.7.1/surefire-booter-2.7.1.jar Scope: compile
[DEBUG] Adding to surefire booter test classpath: /Users/aaron/.m2/repository/org/apache/maven/surefire/surefire-api/2.7.1/surefire-api-2.7.1.jar Scope: compile
Forking command line: /bin/sh -c cd /Users/aaron/Programs/my_program && /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java -jar /Users/aaron/Programs/my_program/target/surefire/surefirebooter6118081963679415631.jar /Users/aaron/Programs/my_program/target/surefire/surefire4887918564882595612tmp /Users/aaron/Programs/my_program/target/surefire/surefire9012255138269731406tmp
-------------------------------------------------------
T E S T S
-------------------------------------------------------
There are no tests to run.
Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.089s
[INFO] Finished at: Mon May 30 12:03:09 EDT 2011
[INFO] Final Memory: 7M/62M
[INFO] ------------------------------------------------------------------------
By default Maven uses the following naming conventions when looking for tests to run:
Test*
*Test
*Tests
(has been added in Maven Surefire Plugin 2.20)*TestCase
If your test class doesn't follow these conventions you should rename it or configure Maven Surefire Plugin to use another pattern for test classes.
I also found that the unit test code should put under the src/test/java
folder, it can not be recognized as test class if you put it under the main folder.
eg.
Wrong
/my_program/src/main/java/NotTest.java
Right
/my_program/src/test/java/MyTest.java
UPDATE:
Like @scottyseus said in the comments, starting from Maven Surefire 2.22.0 the following is sufficient:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
When using JUnit 5, i ran into the same problem. Maven Surefire needs a plugin to run JUnit 5 tests. Add this to our pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0-M1</version>
</dependency>
</dependencies>
</plugin>
Source: https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven
UPDATE 2021
The junit-platform-surefire-provider, which was originally developed by the JUnit team, was deprecated in JUnit Platform 1.3 and discontinued in 1.4. Please use Maven Surefire’s native support instead.
Another thing that can cause Maven to not find the tests if if the module's packaging is not declared correctly.
In a recent case, someone had <packaging>pom</packaging>
and my tests never ran. I changed it to <packaging>jar</packaging>
and now it works fine.
In my case it was adding the junit-vintage-engine which makes it compatible with older version of JUnit tests and can run them. As I'm using JUnit 5.
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
If you created a Spring Boot
application using Spring Initializr, tests are running all right from Intellij Idea.
But, if try to run tests from a command-line:
mvn clean test
You might have been surprised, that no tests were run at all. I tried to add surefire plugin
with no luck.
The answer was simple: pom.xml
contained the following dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
The exclusion, junit-vintage-engine
, is dedicated for keeping backward compatibility with JUnit 4.x
. So, new versions of Spring Boot Initializr do not support it by default.
After I removed the exclusion, Maven
started to see project's tests.
Also, check if your test classes directory (e.g. src/test/java) corresponds to directory listed in property <testSourceDirectory>
in your pom.xml under <build>
property. Took me a while to find that.
Many of these answers were quite useful to me in the past, but I would like to add an additional scenario that has cost me some time, as it may help others in the future:
Make sure that the test classes and methods are public.
My problem was that I was using an automatic test class/methods generation feature of my IDE (IntelliJ) and for some reason it created them as package-private. I find this to be easier to miss than one would expect.
I struggle with this problem. In my case I wasn't importing the right @Test annotation.
1) Check if the @Test is from org.junit.jupiter.api.Test (if you are using Junit 5).
2) With Junit5 instead of @RunWith(SpringRunner.class)
, use @ExtendWith(SpringExtension.class)
import org.junit.jupiter.api.Test;
@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application.properties")
public class CotacaoTest {
@Test
public void testXXX() {
}
}
Maven will not run your tests if the project has <packaging>pom</packaging>
You need to set the packaging to jar (or some other java artefact type) for the tests to run: <packaging>jar</packaging>
Check that (for jUnit - 4.12 and Eclipse surefire plugin)
- Add required jUnit version in POM.xml in dependencies. Do Maven -> Update project to see required jars exported in project.
- Test class is under the folder src/test/java and subdirectories of this folder (or base folder can be specified in POM in config testSourceDirectory). Name of the class should have tailng word 'Test'.
- Test Method in the test class should have annotation @Test
Discovered if you prefix a test with 'Abstract' it will be ignored by default aswell.
Following worked just fine for me in Junit 5
https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
<!-- ... -->
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<!-- ... -->
</dependencies>
<!-- ... -->
I also had similar issue, after exploring found that testng dependency is causing this issue. After removing the testng dependency from pom (as I dont need it anymore), it started to work fine for me.
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version>
<scope>test</scope>
</dependency>
In my case we are migration multimodule application to Spring Boot. Unfortunately maven didnt execute all tests anymore in the modules. The naming of the Test Classes didnt change, we are following the naming conventions.
At the end it helped, when I added the dependency surefire-junit47
to the plugin maven-surefire-plugin
. But I could not explain, why, it was trial and error:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>${maven-surefire-plugin.version}</version>
</dependency>
</dependencies>
If your test class name does not follow the standard naming convention (as highlighted by @axtavt above), you need to add the pattern/class name in the pom.xml
in order to Maven pick the test -
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*_UT.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
...
The Maven Surefire plugin supports several test frameworks. It tries to autodetect which framework you are using, then looks for tests written using that framework. If that autodetection is confused, and chooses the wrong framework, the second stage will not find your tests.
The autodetection works by scanning the classpath for the presence of significant "driver" classes for the test frameworks it supports. Therefore the autodetection can go wrong if your POM, or a depended on module, has an incorrect dependency on one of those "driver" classes.
At present (2020), a particular problem is the difference between JUnit 4 and JUnit 5. The Surefire plugin treats them as different frameworks. But because of the similarity in the package names, a project can have a dependency on the wrong framework but seem OK to a casual inspection.
In particular, beware that junit-platform-console
is for JUnit 5, but junit-platform-runner
is for JUnit 4. If your project has a dependency on the latter, Surefire will not run your JUnit 5 tests.
Here's the exact code I had to add to my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
And here's my dependencies:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert-core</artifactId>
<version>2.0M10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0-M1</version>
</dependency>
</dependencies>
If you have a shared Java / Groovy application and all you have are Groovy unit tests, then Maven won't find any tests. This can be fixed by adding one unit test under src/test/java.
/my_program/src/test/java/ClassUnderTestTests.java
should be
/my_program/src/test/java/ClassUnderTestTest.java
The Maven finds those ends Test or starts with Test to run automatically.
However, you can using
mvn surefire:test -Dtest=ClassUnderTestTests.java
to run your tests.
I faced the same issue , it resolved by below change in pom.xml :
<build>
<testSourceDirectory>test</testSourceDirectory>
...
changed to:
<build>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
One more tip (in addition to the previous answers):
In Eclipse, go to your project's Properties > click Run/Debug Settings
:
"This page allows you to manage launch configurations with the currently selected resource"
In there you can add (New...) or remove (Delete) any JU (JUnit) tests you have in your project (under the src/test/java
folder, or course).
In my case, my parent pom had a parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>some version</version>
<relativePath/>
</parent>
After changing to importing a spring pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>some version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
My unit tests started to run
Probably not a common mistake but in addition to @João Matos's answer. Besides the requirement of your methods being public:
You're methods also should be void
and of course have the @Test
annotation.
This won't work:
@Test
public Integer fooBarTest() {
// omitted
}
It must return a void
:
@Test
public void fooBarTest() {
// omitted
}
Another reason for not running the test cases happened to me - I had a property named "test" for completely different purposes, but it interfered with the surefire plugin. Thus, please check your POMs for:
<properties>
<test>.... </test>
...
</properties>
and remove it.
If you have written your tests in JUnit 4 and added JUnit 5 dependencies to the surefire plugin, your tests will not run.
In that case, just comment JUnit 5 dependencies from surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<!--<dependencies>-->
<!--<dependency>-->
<!--<groupId>org.junit.platform</groupId>-->
<!--<artifactId>junit-platform-surefire-provider</artifactId>-->
<!--<version>1.0.0</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.junit.jupiter</groupId>-->
<!--<artifactId>junit-jupiter-engine</artifactId>-->
<!--<version>${junit.version}</version>-->
<!--</dependency>-->
<!--</dependencies>-->
</plugin>
Such problem might occur when you use surfire plugin 3.x.x+ with JUnit5 and by mistake annotate the test class with @Test
annotation from JUnit4.
Use: org.junit.jupiter.api.Test
(JUnit5) instead of org.junit.Test
(Junit4)
NOTE: this might be hard to notice as the IDE might run this wihout problems just as JUnit4 test.
Another easily overlooked problem I recently experienced - Ensure your Test class' file has the .java extension. If there's no tests to compile, there are no tests to run
junitArtifactName
might also be the case if the JUnit in use isn't the standard (junit:junit
) but for instance...
<dependency>
<groupId>org.eclipse.orbit</groupId>
<artifactId>org.junit</artifactId>
<version>4.11.0</version>
<type>bundle</type>
<scope>test</scope>
</dependency>
In case someone has searched and I do not solve it, I had a library for different tests:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${org.junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
When I installed junit everything worked, I hope and help this:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
精彩评论