535

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>
    </dependencies>
    <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] ------------------------------------------------------------------------
Raedwald
  • 46,613
  • 43
  • 151
  • 237
Aaron Silverman
  • 22,070
  • 21
  • 83
  • 103
  • 2
    For people using spring-boot please check https://stackoverflow.com/a/60831916/990279 – Enrico Jan 02 '21 at 15:03
  • For me IntelliJ tried to "help me" by doing stuff for me and broke the testing. If I have the correct dependency for Junit Jupiter and the correct plugin version for the SureFire plugin, and I use `ALT+ENTER` on a class name to create a test, maven will not recognize the test class and does not run it. However, when I manually create the test file according to the Maven naming conventions it will get recognized by Maven and run. I have yet to figure out how to reverse the process where IntelliJ breaks the testing – Aron Hoogeveen Mar 25 '21 at 18:09
  • When I was refactoring my project to separate main from tests, I accidentally forgot to create the "src/test/java" folder and my packages were therefore starting at src/test instead. This caused the test classes to be missed by the mvn compile goal so when it came time to run tests, there were no compiled test classes. Since eclipse uses an internal test runner, JUnit tests might work perfectly fine in Eclipse but then fail at the command line with Maven. – beaudet Jan 31 '22 at 20:56

34 Answers34

782

By default Maven uses the following naming conventions when looking for tests to run:

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.

Ilya Serbis
  • 21,149
  • 6
  • 87
  • 74
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 7
    I find it more appealing to change the maven config. This naming convention does pose some danger to unexpirienced user. Naming your testcases like SomethingTest1, SomethingTest2 would result in the tests silently not beeing executed. Maven can not do this for backwards compatibility but it does seam more logic to search for testcases in all files. – Tobias Kremer Sep 10 '13 at 11:37
  • 9
    I never knew this - had two cases that ended with "Tests", and maven refused to run them...changed to "Test", and all is well in the lollipop guild again. Thanks. – demaniak May 05 '14 at 10:24
  • 4
    @Tobias I agree with your point about the danger imposed with naming convention. It kind of also breaks the pattern implied by the use of annotations. An implicit result of using annotations is that classes/methods having a specific annotation can be searched. I would have hoped that Maven did not put in place the naming convention restriction and instead relied only on scanning _@Test_ annotated methods in any class. – Angad Dec 29 '14 at 20:42
  • In my case a parent maven has the pattern set to `*Tests`. It took me a long time to find that. – tokosh Mar 28 '16 at 05:44
  • Importantly, the class name must follow the naming convention. MyTests.java fails while MyTest.java is found. – J E Carter II May 10 '17 at 18:11
  • +1 Configure Maven Surefire Plugin: See [Inclusions and Exclusions of Tests](http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html) for a precise example – Adam Taras Sep 07 '17 at 12:07
  • 2
    Note that the surefire documentation _now_ claims that `**/*Tests.java` is a default include! – Gareth Oct 13 '17 at 09:54
  • 2
    @demaniak Same here, 4 years later. Renaming the class name to end with `Test` instead of `Tests` did the magic. – datv May 03 '18 at 10:47
  • 52
    Question: So why annotate with @test if you have to follow Test* convention anyway? – dynex Jul 31 '18 at 11:49
  • 1
    Additionally to that, make sure that you do not have a mix of Junit4 and Junit5 Annotations used in the tests. In my case, i have to test classes in the same package. The first test class (with Junit5 Annotations/@Test) is executed , but the second one was not, since I blindly added @Test (by Alt+Enter) and it apppeared to be Junit4. After replacing it with Junit5 - both tests run – 27P Apr 30 '19 at 08:59
  • 1
    Tobias was right, I was wondering why my tests won't run, turns out it is a stupid way of how Maven looks for what qualifies as a test class. – Harvey Lin Oct 14 '19 at 21:37
  • 3
    I don't understand why can't they just check every class under the "test" folder. Or at least look also for the pattern "Tests". That way we don't have to add an extra dependency – GabrielBB Jan 16 '20 at 03:21
  • 5
    @dynex - you can have "helper" methods in the test class. Like, if your test is getting some data and you have a standard way of converting this data to something assertable. You can have one method that converts the data for all your test methods but this method isn't a test by itself. This is where the annotation comes handy. PS: *Test naming convention is just stupid. The last thing a programmatic framework needs is obscure and very specific logic. I am sure this catches thousands of testers worldwide every year! – DraxDomax Mar 04 '20 at 10:57
  • Notice that if you use the `includes` configuration it will not include any default values... – Yogev Levy Jan 19 '22 at 10:57
  • what _sucks_ the most is that surefire never bothered to add a feature like: "if you do not follow the naming convention and I can spot that, I will fail the build". The more I use this plugin, the more I wish it wasn't developed by apache... – Eugene May 13 '23 at 13:02
124

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
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Robin Ma
  • 1,249
  • 1
  • 8
  • 3
  • 3
    Thaaank you! This and setting the scope to test (`test`) in the `pom.xml` file did it for me. – dinesharjani May 22 '17 at 18:28
  • 2
    I ran into this, watch out for tests vs test. The proper one is test – Bruck Wubete Nov 08 '19 at 17:00
  • Thanks, that was my issue and i solved it thanks to your comment. – eladyanai Aug 06 '20 at 16:43
  • I dont believe that your answer is correct anymore. If you specify as an example: `src/main/java/com/packageNameA/packageNameB/tests` within you pom.xml's `` section, tests should be picked up just fine when running somehting like `mvn clean test`. (Tested with `maven-surefire-plugin 3.0.0`) – BernardV May 02 '23 at 07:33
120

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.

Paul Verest
  • 60,022
  • 51
  • 208
  • 332
teyzer
  • 1,440
  • 1
  • 10
  • 14
  • 2
    I'm getting a "not found" for `junit-platform-surefire-provider`. – Arya Pourtabatabaie Sep 24 '18 at 19:22
  • 4
    Note that with Surefire 2.22, it shouldn't be necessary to add dependencies on the `surefire-provider` or `jupiter-engine` artifacts. My tests seem to run fine without them, at least. see [this answer](https://stackoverflow.com/a/49019437/2434726). – scottysseus Dec 11 '18 at 17:23
  • 7
    It is also worth noting that you must use `org.junit.jupiter.api.Test` instead of `org.junit.Test` when using this plugin or the tests will not be found. – austin_ce Feb 13 '19 at 20:10
  • 1
    works when surefire plugin is added with junit 5 dependencies – Gaurav Sep 28 '20 at 00:04
  • @austin_ce that's it! Meanwhile, this makes it incompatible with mockito `@Mock` and the whole test module becomes useless :( Now need the solution for this :) – RAM237 Feb 11 '21 at 08:46
  • This [JUnit5 documentation](https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven) shows how you would configure Maven with JUnit5 v5.8.1 and `maven-surefire-plugin` v2.22.2 right now. It also shows how to run JUnit4 in parallel. – Avec Oct 15 '21 at 00:11
  • If your project configured with junit4 and using a spring-boot-test version that brings in `junit-jupiter`/junit-5 then exclude those deps from the dependecny in order for maven to execute the UT's – Nanotron Apr 19 '22 at 11:01
  • Met similar problem and fixed it. Current project used JUnit5 + Surefire 2.21.0, and we observed that surefire is running 0 test during maven operation. Updating surefire to 2.22.0 fixed the issue. – Xiang Wei Huang Oct 21 '22 at 06:35
99

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.

Jon
  • 3,212
  • 32
  • 35
54

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>
Duc Tran
  • 6,016
  • 4
  • 34
  • 42
  • I think SpringBoot only includes what it uses. It makes sense that you have to specify your dependencies according to your needs. Otherwise, you'll be importing a whole bunch of libraries which you don't use. – Duc Tran Sep 09 '19 at 18:00
  • FYI, this is actually mentioned in [the Spring Boot 2.4 upgrade instructions](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.4-Release-Notes) – Didier L Mar 30 '22 at 08:21
49

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.

Exterminator13
  • 2,152
  • 1
  • 23
  • 28
  • Big Help. Thanks. The default runner was JUnit5, even though you can manually run the tests from the context menu, it will not work in the terminal until you remove the exclusions you mentioned. – Vectoria Nov 17 '20 at 03:13
  • 9
    I had not the exclusion, but had to explicitly specify the dependency junit-vintage-engine. I thought it was implicit but it was not. – Enrico Jan 02 '21 at 15:02
  • I had the exact same problem. Thanks. I was like: why isn't this running. Some comments actually recommend excluding the junit vintage... – Vivere Feb 17 '21 at 19:55
  • I also did't have exclusion but junit 4 tests were not working. After adding junit-vintage-engine it worked, thanks. – Bhdr Sep 22 '21 at 18:32
  • 1
    Super weird but adding the dependency worked. Thanks @Enrico ``` org.junit.vintage junit-vintage-engine 5.9.1 test ``` – Sankalp Nov 17 '22 at 08:10
38

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.

t3rmin41
  • 668
  • 2
  • 8
  • 18
  • This worked for me as well. I added this property under the build tag, and this made maven compile the test classes into the target folder under a folder named test-classes. This is the default directory that the surefire plugin checks in order to run the tests. – Bouramas Oct 30 '20 at 10:13
33

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.

João Matos
  • 6,102
  • 5
  • 41
  • 76
  • 1
    This is the problem I had also, for some reason IntelliJ is creating tests as package-private and Maven cannot see them. Changing the class and @Test method to public made maven execute the tests. – AlexC Jan 05 '19 at 19:26
  • Solved my problem! Note that this doesn't apply to JUnit 5+. I guess IntelliJ's code generator assumes you're using the latest version. – lamino Jun 26 '19 at 19:48
  • @lamino I was using junit5 and it was failing because my test method was not public – SudhirKumar Sep 21 '19 at 05:45
  • A bit cheeky from IntelliJ to tell me that the methods can be package-private .. – Wecherowski Oct 19 '19 at 22:29
23

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() {

    }
}
Eduardo Briguenti Vieira
  • 4,351
  • 3
  • 37
  • 49
  • For me worked after using org.junit.jupiter.api.Test. I did not need to use @ExtendWith(SpringExtension.class) – user07 Dec 30 '20 at 07:17
  • when using that it works for maven but junit cannot run the tests any more (wrong test class) – Kaspatoo Jan 11 '22 at 19:01
14

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>

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • But is there a way to make it work with packaging of `pom` since my project needs it (multi-module project) ? – Frederic Nov 17 '21 at 21:40
11

Check that (for jUnit - 4.12 and Eclipse surefire plugin)

  1. Add required jUnit version in POM.xml in dependencies. Do Maven -> Update project to see required jars exported in project.
  2. 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'.
  3. Test Method in the test class should have annotation @Test
Mitra
  • 318
  • 4
  • 7
  • 1
    This is more of a java config issue, but in addition to naming the test class properly and putting the test file in the test directory under src, the package name of the test class must match the package name of the class you are testing. – Paul May 29 '15 at 13:39
  • 2
    @Paul False - Maven will execute [all classes matching the convention under `src/test/java`](http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html). The package convention is for structure and to allow tests access to package-private methods. – Michael K Aug 24 '15 at 18:02
11

Discovered if you prefix a test with 'Abstract' it will be ignored by default aswell.

user1016765
  • 2,935
  • 2
  • 32
  • 48
9

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>
<!-- ... -->
A. S. Ranjan
  • 355
  • 4
  • 4
  • Thanks. In your example you include junit-jupiter-api and junit-jupiter-engine. Using the same I got some errors in the building phase. However, following the link you provided, I learn that including only junit-jupiter (version 5.6.2) works fine. – Pedro García Medina Jun 20 '20 at 03:02
  • I didn't have to import the plugins. Adding `junit-jupiter-engine` dependecy did the work. – havryliuk May 05 '22 at 07:14
8

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>

Michael Hegner
  • 5,555
  • 9
  • 38
  • 64
  • 1
    Thanks - this is only of dozen solutions that worked for us. – Nenad Bulatović Dec 01 '20 at 22:50
  • This explains why is this used: https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html – Nenad Bulatović Dec 01 '20 at 23:08
  • I've read about it in Surefire documentation just a few minutes ago, so once saw this answer decided to try immediately. Now executes 1120 instead of 150 which sounds like a good progress, but still way far from running ALL tests... – RAM237 Feb 11 '21 at 09:37
7

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>
6

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> 
...
Saikat
  • 14,222
  • 20
  • 104
  • 125
  • But be aware that that will overwrite the default configuration. If you also have test classes named according to the pattern *Test.java, these will not be executed! – AnnetteC Apr 07 '22 at 07:32
6

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.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
5

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>
fIwJlxSzApHEZIl
  • 11,861
  • 6
  • 62
  • 71
4

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.

bruce szalwinski
  • 724
  • 1
  • 8
  • 27
4
/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.

Boris Z.
  • 49
  • 4
4

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>
ShayneR
  • 466
  • 4
  • 8
3

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>
youhans
  • 6,101
  • 4
  • 27
  • 39
2

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

datv
  • 585
  • 3
  • 15
2

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

Rostislav V
  • 1,706
  • 1
  • 19
  • 31
  • This solution worked for my problem which is a bit more challenging; my Spring Boot 3.4.12 application was running the tests locally but was skipping them during the GCP Cloud Build. – Cortex Feb 10 '22 at 01:33
2

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
}
luukvhoudt
  • 1,726
  • 19
  • 33
1

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.

Rusi Popov
  • 377
  • 1
  • 6
1

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.

walkeros
  • 4,736
  • 4
  • 35
  • 47
1

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

Mark W
  • 5,824
  • 15
  • 59
  • 97
  • Class files are compiled to .class which have nothing to do with testing source files. – ShadowGames Nov 26 '20 at 10:13
  • 1
    I was referring to the test classes, and when I say Class I am not referring to the file type, you've misinterpreted. I'll make my answer clearer – Mark W Dec 01 '20 at 14:16
1

Please make sure to use junit-jupiter and NOT junit-jupiter-api (which I used accidentally)

  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.0</version>
    <scope>test</scope>
  </dependency>
s-gbz
  • 402
  • 8
  • 11
0

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>
Tuomas Kiviaho
  • 355
  • 3
  • 9
0

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>
hizmarck
  • 686
  • 9
  • 19
0

Faced this issue while working on a spring boot project setup with Junit4. Jacoco maven plugin always returned 0.00 test coverage and maven surefire plugin ran 0 tests.

Removed junit-vintage-engine and surefire-junit47 dependency and added the following dependencies to run Junit 5 unit tests.

 <dependency>
   <groupId>org.junit.jupiter</groupId>
   <artifactId>junit-jupiter-engine</artifactId>
   <version>5.6.2</version>
   <scope>test</scope>
 </dependency>

Adding version lower than 5.6.2 led to ScriptEvaluationException.

Also using @ExtendWith(SpringExtension.class) instead of@RunWith(SpringRunner.class)

Ajay V
  • 523
  • 5
  • 11
0

I tried most of the answers in this thread but I got it working only when I did the following to my pom.xml.

It had the org.junit.jupiter as a seperate dependency

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

But then I moved the same inside the maven-surefire-plugin plugin and the mvn clean install/test started detecting my test files which was under src/test/java

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.21.0</version>
    <dependencies>
    <!-- moved here -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.2.0</version>
        </dependency>
    </dependencies>
</plugin>
Akhil
  • 368
  • 4
  • 16
0

Using Surefire plugin you might want to include all the files for testing:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M7</version>
    <configuration>
        <includes>
            <include>*</include>
        </includes>
    </configuration>
</plugin>

this way you can get all your files tested, not only the ones that include the pattern that Surefire requires.

Benjamin
  • 3,217
  • 2
  • 27
  • 42