How do I get my Maven Integration tests to run

255,735

Solution 1

You can set up Maven's Surefire to run unit tests and integration tests separately. In the standard unit test phase you run everything that does not pattern match an integration test. You then create a second test phase that runs just the integration tests.

Here is an example:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <excludes>
          <exclude>**/*IntegrationTest.java</exclude>
        </excludes>
      </configuration>
      <executions>
        <execution>
          <id>integration-test</id>
          <goals>
            <goal>test</goal>
          </goals>
          <phase>integration-test</phase>
          <configuration>
            <excludes>
              <exclude>none</exclude>
            </excludes>
            <includes>
              <include>**/*IntegrationTest.java</include>
            </includes>
          </configuration>
        </execution>
      </executions>
    </plugin>

Solution 2

The Maven build lifecycle now includes the "integration-test" phase for running integration tests, which are run separately from the unit tests run during the "test" phase. It runs after "package", so if you run "mvn verify", "mvn install", or "mvn deploy", integration tests will be run along the way.

By default, integration-test runs test classes named **/IT*.java, **/*IT.java, and **/*ITCase.java, but this can be configured.

For details on how to wire this all up, see the Failsafe plugin, the Failsafe usage page (not correctly linked from the previous page as I write this), and also check out this Sonatype blog post.

Solution 3

I have done EXACTLY what you want to do and it works great. Unit tests "*Tests" always run, and "*IntegrationTests" only run when you do a mvn verify or mvn install. Here it the snippet from my POM. serg10 almost had it right....but not quite.

  <plugin>
    <!-- Separates the unit tests from the integration tests. -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
       <!-- Skip the default running of this plug-in (or everything is run twice...see below) -->
       <skip>true</skip>
       <!-- Show 100% of the lines from the stack trace (doesn't work) -->
       <trimStackTrace>false</trimStackTrace>
    </configuration>
    <executions>
       <execution>
          <id>unit-tests</id>
          <phase>test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
                <!-- Never skip running the tests when the test phase is invoked -->
                <skip>false</skip>
             <includes>
                   <!-- Include unit tests within integration-test phase. -->
                <include>**/*Tests.java</include>
             </includes>
             <excludes>
               <!-- Exclude integration tests within (unit) test phase. -->
                <exclude>**/*IntegrationTests.java</exclude>
            </excludes>
          </configuration>
       </execution>
       <execution>
          <id>integration-tests</id>
          <phase>integration-test</phase>
          <goals>
             <goal>test</goal>
          </goals>
          <configuration>
            <!-- Never skip running the tests when the integration-test phase is invoked -->
             <skip>false</skip>
             <includes>
               <!-- Include integration tests within integration-test phase. -->
               <include>**/*IntegrationTests.java</include>
             </includes>
          </configuration>
       </execution>
    </executions>
  </plugin>

Good luck!

Solution 4

You can split them very easily using JUnit categories and Maven.
This is shown very, very briefly below by splitting unit and integration tests.

Define A Marker Interface

The first step in grouping a test using categories is to create a marker interface.
This interface will be used to mark all of the tests that you want to be run as integration tests.

public interface IntegrationTest {}

Mark your test classes

Add the category annotation to the top of your test class. It takes the name of your new interface.

import org.junit.experimental.categories.Category;

@Category(IntegrationTest.class)
public class ExampleIntegrationTest{

    @Test
    public void longRunningServiceTest() throws Exception {
    }

}

Configure Maven Unit Tests

The beauty of this solution is that nothing really changes for the unit test side of things.
We simply add some configuration to the maven surefire plugin to make it to ignore any integration tests.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.11</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <excludedGroups>
            com.test.annotation.type.IntegrationTest
        </excludedGroups>
    </configuration>
</plugin>

When you do a mvn clean test, only your unmarked unit tests will run.

Configure Maven Integration Tests

Again the configuration for this is very simple.
We use the standard failsafe plugin and configure it to only run the integration tests.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <includes>
            <include>**/*.class</include>
        </includes>
        <groups>
            com.test.annotation.type.IntegrationTest
        </groups>
    </configuration>
</plugin>

The configuration uses a standard execution goal to run the failsafe plugin during the integration-test phase of the build.

You can now do a mvn clean install.
This time as well as the unit tests running, the integration tests are run during the integration-test phase.

Solution 5

You should use maven surefire plugin to run unit tests and maven failsafe plugin to run integration tests.

Please follow below if you wish to toggle the execution of these tests using flags.

Maven Configuration

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>${skipUnitTests}</skipTests>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <includes>
                    <include>**/*IT.java</include>
                </includes>
                <skipTests>${skipIntegrationTests}</skipTests>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <properties>
            <skipTests>false</skipTests>
            <skipUnitTests>${skipTests}</skipUnitTests>
            <skipIntegrationTests>${skipTests}</skipIntegrationTests>
        </properties>

So, tests will be skipped or switched according to below flag rules:

Tests can be skipped by below flags:

  • -DskipTests skips both unit and integration tests
  • -DskipUnitTests skips unit tests but executes integration tests
  • -DskipIntegrationTests skips integration tests but executes unit tests

Running Tests

Run below to execute only Unit Tests

mvn clean test

You can execute below command to run the tests (both unit and integration)

mvn clean verify

In order to run only Integration Tests, follow

mvn failsafe:integration-test

Or skip unit tests

mvn clean install -DskipUnitTests

Also, in order to skip integration tests during mvn install, follow

mvn clean install -DskipIntegrationTests

You can skip all tests using

mvn clean install -DskipTests
Share:
255,735

Related videos on Youtube

Peter Delaney
Author by

Peter Delaney

Software developer focusing mostly with integration of applications using SOAP/REST, JMS and other integration technologies. Experienced deploying applications in AWS cloud environment and AWS Architect/Developer/SysOps Associate certified.

Updated on February 11, 2022

Comments

  • Peter Delaney
    Peter Delaney over 2 years

    I have a maven2 multi-module project and in each of my child modules I have JUnit tests that are named Test.java and Integration.java for unit tests and integration tests respectively. When I execute:

    mvn test

    all of the JUnit tests *Test.java within the child modules are executed. When I execute

    mvn test -Dtest=**/*Integration

    none of the Integration.java tests get execute within the child modules.

    These seem like the exact same command to me but the one with the -Dtest=/*Integration** does not work it displays 0 tests being run at the parent level, which there are not any tests

    • heenenee
      heenenee over 8 years
      Kief's answer should be the accepted one, as it is the current standard for defining integration tests in Maven.
  • Peter Delaney
    Peter Delaney over 14 years
    Hi and thanks I have two kinds of tests normal POJO Junit tests called SomethingTest.java which get fired. I also have integration tests called SomethingIntegration.java which do not get fired. The SomethingTest.java get fired via mvn test or mvn install. The second tests do not get fired. mvn test -Dtest=**/*Integration
  • Peter Delaney
    Peter Delaney over 14 years
    I configured this as you said and only the *Test not the *Integration.java files will run when executing: mvn install I need to run my *Test.java as the default, but for my nightlty build I need to run both *Test.java and *Integration.java. I have to execute mvn install then cd to each sub-child directory and execute mvn -Dtest=**/*Integration test
  • mdma
    mdma about 13 years
    +1 This is what I use. Works well, and allows you to do pre/post setup, such as starting and shutting down a local servlet container.
  • Joshua Davis
    Joshua Davis almost 13 years
    Why wouldn't you use the integration-test phase? Profiles can then be used for things like integration-testing against various app servers, etc. like Arquillian does. I'm not a Maven expert, but I think the experts might say this is not very 'Maven-y'.
  • Joshua Davis
    Joshua Davis almost 13 years
    .. and by "Maven only runs tests that have Test somewhere in the class name" you mean "the Maven surefire plugin only runs tests that have Test somewhere in the class name".
  • Jorge
    Jorge almost 13 years
    @Joshua I guess I do it this way because my integration tests take at least 5 minutes to run and I issue 'mvn clean install' many times a day because I need to update my artifacts in my local maven repo. According to what people are saying above, running 'install' will cause the integration-test phase to run causing me to lose precious developer time.
  • Joshua Davis
    Joshua Davis almost 13 years
    Hmm... not sure about 'install' running integration-test. In any case I'd still use the phase instead of a profile. Profiles are better off used for things like supporting different app servers, etc.
  • Jorge
    Jorge almost 13 years
    I'll go ahead and play around with that then. Thanks for the advice!
  • Dave
    Dave over 12 years
    Then feel free to check the box for this response being the answer!
  • John Gordon
    John Gordon about 12 years
    You should use the Fail-safe plugin for integration testing, not the sure-fire plugin. It won't fail the build until after the post-integration phase is complete; allowing you to tear down test resources (a web server, for example) before the build is failed. Hence, fail-safe.
  • Julian
    Julian almost 12 years
    Its not "somewhere in the classname" its "the class name ends with Test", for example MyTest works but MyTests doesn't
  • Kilokahn
    Kilokahn over 11 years
    @jorge I guess the correct goal to use here would be verify, right?
  • Tarun Kumar
    Tarun Kumar about 11 years
    for me, as part of pre-integration phase, jetty server starts. Last log line is : [INFO] Started Jetty Server. After that, nothing happens. It gets stuck. maven surefire failsafe plugin doesn't execute tests nor jetty server stops. Any idea what's wrong? I am using same configuration as specified by you.
  • DeejUK
    DeejUK almost 11 years
    This only works if the marker interface already exists somewhere available to Maven. It does not work if your marker interface exists in another module of the same multi-module build.
  • Jin Kwon
    Jin Kwon about 10 years
    maven-failsafe-plugin has gone to Plugin Graveyard
  • V Krishan
    V Krishan about 10 years
    The graveyard page just says the failsafe plugin has been moved to maven-failsafe-plugin. It looks like the maven-failsafe-plugin is still active (docs were last pushed March 2014).
  • Jin Kwon
    Jin Kwon almost 10 years
    @WillV Correct. The Codehaus' graveyard. And the maven-failsafe-plugin is in Apache now. Sorry. :)
  • Shadow Man
    Shadow Man almost 10 years
    By default mvn integration-test also runs unit tests (using via surefire) but mvn failsafe:integration-test runs only the failsafe integration tests.
  • Henno Vermeulen
    Henno Vermeulen over 8 years
    Incredibly, the Failsafe plugin documentation, usage page and FAQ do not mention that it runs test classes named */IT.java, **/*IT.java, and **/*ITCase.java...
  • SujitS
    SujitS over 8 years
    What if I use excludedGroups instead of exclude in default one. I tried that but I cannot run the integration-tests with that. While I tried mvn clean install -P integration-tests it ignores the excluded group and test categorized with integration-tests wont run.
  • Neill Lima
    Neill Lima over 7 years
    This should be the accepted answer. The associated maven goal is: clean compile integration-test -Dmaven.test.failure.ignore=false
  • Bruce Sun
    Bruce Sun over 7 years
    If it runs after package phase, that means I should put all my IT java source code under src/main/java instead of src/test/java right?
  • Joshua Taylor
    Joshua Taylor over 7 years
    @HennoVermeulen I was confused about what to name tests as well. It's described in Inclusions and Exclusions of Tests. It's nice that the defaults can be overridden, but it'd be nice if they'd mention the defaults earlier on.
  • Zac Thompson
    Zac Thompson over 6 years
    This answer is very out of date and should be updated or removed.
  • Rohit Barnwal
    Rohit Barnwal over 6 years
  • Praveen Tiwari
    Praveen Tiwari over 5 years
    @HennoVermeulen it does, see here maven.apache.org/surefire/maven-failsafe-plugin/…
  • Praveen Tiwari
    Praveen Tiwari over 5 years
  • Henno Vermeulen
    Henno Vermeulen over 5 years
    @p_champ you are right, I guess I didn't look well enough
  • Jacob van Lingen
    Jacob van Lingen almost 5 years
    @BruceSun: Neither, put them under src/it/java, see also khmarbaise.github.io/maui/it-example-1.html
  • Nexonus
    Nexonus over 3 years
    Without additional configuration in the surefire plugin the IT tests did not run although my IT tests fit the default naming pattern. However calling mvn clean test-compile failsafe:integration-test did execute them directly. (Source: stackoverflow.com/a/43470158/9478795)
  • Jorge Muñoz
    Jorge Muñoz over 2 years
    Exactly the solution that I have been searching for may hours. Works fine!, Thankyou Liquidpie.
  • king pong
    king pong over 2 years
    Am I really MAD if I find it UNBELIEVABLE when such an ESSENTIAL functionality like this SIMPLE separation of running Unit-tests or Integration-tests still isn't working RELIABLY in Maven ? Do I really want too much ?
  • Derlin
    Derlin about 2 years
    UPDATE: the skipXXTests trick doesn't work anymore. As of version 3.0.0 of failsafe, the <skipTests> option has been removed. Now, we need to use -DskipITs to skip integration tests, -DskipTests to skip all tests, and mvn integration-test to only run its (no unit tests).