Is there a way to skip only a single test in maven?
Asked Answered
T

6

87

I would like to skip only a single test while launching mvn install.

Is there a way to do that ?

Terrijo answered 7/5, 2009 at 16:26 Comment(3)
maven.apache.org/surefire/maven-surefire-plugin/examples/…Illtreat
If you're using the failsafe plugin: mvn clean install -Dit.test=\!TestToSkip.*Land
If someone is using JUnit 5, this might be useful: mkyong.com/junit5/junit-5-how-to-disable-testsCoherent
K
24

With junit 4, I add an @Ignore annotation when I want to do that. This would work for you, unless you want to only sometimes ignore the test, or only ignore it when the build runs from maven. If this is the case, then I would ask "Why?"

Tests should be consistent, they should be portable, and they should always pass. If a specific test is problematic I would consider re-writing it, removing it entirely, or moving it to a different test suite or project.

Known answered 7/5, 2009 at 16:49 Comment(11)
The use case is that someone in my team is currently fixing a test and I want to launch all others tests but not this one until it's working again. So you're right, I should disabled it by code temporary.Terrijo
This also works on a class level. I have a base test and the pom configuration is unchangable (it's in a shared parent pom), so Maven fails my tests because it says "no tests" in the abstract class. This is one great solution.Mislay
This means you have to edit/commit to reverse the change. Same for the next solution:Bonney
Kind of disagree that all tests should be portable, etc. Unit tests, yes, but there is a valid reason to write integration tests to make sure you can wire a data source at development time, rather than waiting until deploy time. These tests shouldn't be run on build, and only to test configuration while in development.Bashemath
I disagree with Steve Reed. I have a test that is failing in my environment that is not related to my work which I don't want to put @Ignore into the code because I have other changes. So I want to skip it during a maven build "mvn clean install". I don't want to spend time analyzing it or fixing it because I clearly know that it is not my area and I can make better use of my time working on other stuff. So a good answer to this question makes a lot of sense.Drewdrewett
I have a situation that part of my application is dependent on some Linux software that is not available on Windows (plus it is too resource demanding for a laptop). However I am developing on a Windows laptop. So I would like to skip all tests related to this part of application during the development phase but still be able to make it when do an official build/release on the Linux box.Gismo
So preachy... @Ignore isn't always ideal. Consider a test by someone else, and yes it's bad (failing if run too often, but passing initially) but no you don't have time to fix it, nor time to convince someone to take it out or fix it themselves, and you don't want to accidentally commit the ignore since it does actually test something valuable most of the time... +1 to the other guy who actually answered the question.Clinkerbuilt
Yep, I don't like the "know it all" arguing with the question either. We don't live in a perfect world and need convenient solutions. If this world were perfect then the concept of bug tracking systems wouldn't exist. In my use case, someone else has written a test that only fails locally but succeeds in the build job. I don't know why exactly, but something to do with file system permissions (wanting write access to '/' - which I don't have time to solve).Rasp
How is this the accepted answer, when it doesn't answer the question?Shiri
One argument might be that a test requires a good internet connection, you might not always have that when working on the go, but you want to run the test in your CI.Flu
Different categories of tests might need and likely need to run in different contexts. Once clean example would be integration tests, or end-to-end tests. While put unit tests should likely run by default. Using @Ignore is the equivalent of not writing the tests.Heiner
U
75

You can specify an exclusion pattern to -Dtest option by prefixing it with an ! (exclamation mark). E.g.,

mvn -Dtest=\!FlakyTest* install

Found it in here and verified to be working. E.g., I was able to skip this flaky Jenkins test by using:

mvn -Dtest=\!CronTabTest* package
Unpredictable answered 13/6, 2016 at 15:55 Comment(6)
That feature was implemented in 2.19, see the documentation.Midshipman
Is there a way to combine include and excludes? E.g. I may want to run Cron*Test except CronFlakyTest. I tried mvn -Dtest="\!CronFlakyTest,Cron*Test" install but that still runs the flaky testRasp
Warning: While useful, this can trash your exclusion rules---such as causing cucumber integration tests to be run during unit testing.Mana
You can skip multiple tests by name with this syntax as well: mvn test -Dtest=\!FirstTestClass,\!SecondTestClassStalagmite
I'm getting No tests were executed! (Set -DfailIfNoTests=false to ignore this error. Although the test log contains something like: ` Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.071 s - Test1... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.071 s - Test2...` not sure how to interpret it...Credent
@Credent Make sure maven-surefire-plugin is at least version 2.19. Also on Windows it has to be "-Dtest=!CronTabTest".Sorites
K
24

With junit 4, I add an @Ignore annotation when I want to do that. This would work for you, unless you want to only sometimes ignore the test, or only ignore it when the build runs from maven. If this is the case, then I would ask "Why?"

Tests should be consistent, they should be portable, and they should always pass. If a specific test is problematic I would consider re-writing it, removing it entirely, or moving it to a different test suite or project.

Known answered 7/5, 2009 at 16:49 Comment(11)
The use case is that someone in my team is currently fixing a test and I want to launch all others tests but not this one until it's working again. So you're right, I should disabled it by code temporary.Terrijo
This also works on a class level. I have a base test and the pom configuration is unchangable (it's in a shared parent pom), so Maven fails my tests because it says "no tests" in the abstract class. This is one great solution.Mislay
This means you have to edit/commit to reverse the change. Same for the next solution:Bonney
Kind of disagree that all tests should be portable, etc. Unit tests, yes, but there is a valid reason to write integration tests to make sure you can wire a data source at development time, rather than waiting until deploy time. These tests shouldn't be run on build, and only to test configuration while in development.Bashemath
I disagree with Steve Reed. I have a test that is failing in my environment that is not related to my work which I don't want to put @Ignore into the code because I have other changes. So I want to skip it during a maven build "mvn clean install". I don't want to spend time analyzing it or fixing it because I clearly know that it is not my area and I can make better use of my time working on other stuff. So a good answer to this question makes a lot of sense.Drewdrewett
I have a situation that part of my application is dependent on some Linux software that is not available on Windows (plus it is too resource demanding for a laptop). However I am developing on a Windows laptop. So I would like to skip all tests related to this part of application during the development phase but still be able to make it when do an official build/release on the Linux box.Gismo
So preachy... @Ignore isn't always ideal. Consider a test by someone else, and yes it's bad (failing if run too often, but passing initially) but no you don't have time to fix it, nor time to convince someone to take it out or fix it themselves, and you don't want to accidentally commit the ignore since it does actually test something valuable most of the time... +1 to the other guy who actually answered the question.Clinkerbuilt
Yep, I don't like the "know it all" arguing with the question either. We don't live in a perfect world and need convenient solutions. If this world were perfect then the concept of bug tracking systems wouldn't exist. In my use case, someone else has written a test that only fails locally but succeeds in the build job. I don't know why exactly, but something to do with file system permissions (wanting write access to '/' - which I don't have time to solve).Rasp
How is this the accepted answer, when it doesn't answer the question?Shiri
One argument might be that a test requires a good internet connection, you might not always have that when working on the go, but you want to run the test in your CI.Flu
Different categories of tests might need and likely need to run in different contexts. Once clean example would be integration tests, or end-to-end tests. While put unit tests should likely run by default. Using @Ignore is the equivalent of not writing the tests.Heiner
A
18

It is normal that integration tests need to be excluded but unit tests need to be included. To achieve this I suggest naming all integration tests with a postfix IntegrationTest (e.g. AbcIntegrationTest.java).

and then in your maven build put the following:

  <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>**/*IntegrationTest.java</exclude>
                </excludes>
            </configuration>
        </plugin>

When you build with this all the integration tests wil be excluded, but all other tests (Unit test for example) are run. Perfect :-)

For more info on exclusing and including tests during the test run, read

http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html

PS To exlude one single test you simply need to explicitly name it in the exclude list. Easy.

Anissa answered 26/9, 2013 at 9:25 Comment(1)
That looks great, but how do you run the integration tests?Staciestack
L
13

If you want to use the CLI to exclude one single test you should use the -Dtest and -Dit.test flags.

Be careful to reset the defaults. When you are using the ! notation all the defaults are erased and you should put them back. For normal tests executed by surefire you should add *Test, Test*, *Tests, *TestCase, while for integration tests executed by failsafe you should add IT*, *IT, *ITCase.

You can find more info here https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html (normal tests)

and here https://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html (integration tests)

-Dit.test='!ITsometestIT, IT*, *IT, *ITCase'

A complete mvn command could be this one:

mvn -e -B -Dtest='!unitTestABC, *Test, Test*, *Tests, *TestCase' -Dit.test='!ITintegrationTestABCIT, IT*, *IT, *ITCase' -DfailIfNoTests=false clean install

Remember to use ' and NOT ". When using double quotes any ! inside them will be evaluated by bash.

Remember also that integration tests are not run when mvn test. With mvn verify only integration tests will be run and not unit tests

Libation answered 26/10, 2018 at 12:18 Comment(0)
U
10

Have a look at this solution, using @Category annotations

public class AccountTest {

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeSomeTime() {
        ...
    }

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeEvenLonger() {
        ...
    }

    @Test
    public void thisOneIsRealFast() {
        ...
    }
}

Which you then run using a test suite:

@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
@SuiteClasses( { AccountTest.class, ClientTest.class })
public class LongRunningTestSuite {}

You also can include (groups) / exclude (excludedGroups) those tests with maven using for exemple:

mvn -DexcludedGroups=com.mycompany.tests.IntegrationTests test
Unhorse answered 9/12, 2011 at 7:31 Comment(1)
Is it possible to specify the category on the maven command line/without touching the code?Tarragona
C
5

i think this should work if using this command:

mvn archetype:create -DgroupId=test -DartifactId=test

(for test change pom.xml and test-class to the following and use mvn install)

pom.xml

<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>test</groupId>
<artifactId>test</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>test</name>
<url>http://maven.apache.org</url>
<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>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        test/AppTest.java
              </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.5</version>
        <scope>test</scope>
    </dependency>
</dependencies>

test-class:

package test;
import org.junit.Test;
import static org.junit.Assert.fail;
public class AppTest 
{
    @Test
    public void test_it() {
        fail("not implemented");
    }
}
Compulsive answered 19/5, 2009 at 7:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.