I've been trying to figure this out for months, and thought it should have been simple. All I wanted to do was write a set of unit tests to test my java code, have them run whenever I hit test. Next I wanted to have a set of HTTP Unit, Selenium or similar tests run to test that the actual application is working when it's built and deployed to a container using the cargo plugin. I didn't really want to have a separate project to do this because it seemed like a massive pain in the ass to maintain the whole thing. I didn't see any reason why it shouldn't be easy with Maven either - it does have a phase for integration-tests already. My first try looked good to me:  
... <build> ...     <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/integration/**</exclude> </excludes> </configuration> <executions> <execution> <id>integrationtest</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/integration/**/*Test*.java</include> <include>**/integration/**/*Test.java</include> <include>**/integration/**/*TestCase.java</include> </includes> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ...
  I tried to run the tests, but unfortunately when it gets to the second round of tests - which should run my integration tests - it runs the same sets of as it ran the first time. I tried adding the combine.children="append" attribute to the includes, and excludes but that didn't work either. Finally I came across a source file XppDom, part of plexus which maven uses. XppDom allowed the combine.children attribute as well as another I haven't seen mentioned anywhere else childMergeOverride. I added that instead and it worked!  
... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/integration/**</exclude> </excludes> </configuration> <executions> <execution> <id>integrationtest</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <excludes childMergeOverride="true"> <exclude>none</exclude> </excludes> <includes childMergeOverride="true"> <include>**/integration/**/*Test*.java</include> <include>**/integration/**/*Test.java</include> <include>**/integration/**/*TestCase.java</include> </includes> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ...
   

Setting it up for Cargo

I've done this on a few projects, the first was a project that built a series of taglibs which are used across a number of applications. The release for the project is a jar so I have a separate test web-app structure in ${baseDir}/src/test/web-app. The code for generating this war looks like this:  
... <build> ... <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <executions> <execution> <id>generate-test-war</id> <phase>pre-integration-test</phase> <goals> <goal>war</goal> </goals> </execution> </executions> <configuration> <warSourceDirectory>${basedir}/src/test/webapp</warSourceDirectory> <warName>${project.artifactId}-test</warName> <webappDirectory>${basedir}/target/${project.artifactId}-test</webappDirectory> <primaryArtifact>false</primaryArtifact> </configuration> </plugin> ... </plugins> ... </build> ...
  During the pre-integration-test phase the above simple generates a test war. If you're project is a web-app and it already generates a war you can skip the above as one will be generated for you already. The next step for was then to get Cargo to deploy the application:  
... <build> ... <plugins> ... <plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <configuration> <wait>false</wait> <container> <containerId>tomcat5x</containerId> <zipUrlInstaller> <url>${integrationtests.tomcatURL}</url> <installDir>${installDir}</installDir> </zipUrlInstaller> <output> ${project.build.directory}/tomcat5x.log </output> <log>${project.build.directory}/cargo.log</log> </container> <configuration> <home> ${project.build.directory}/tomcat5x/container </home> <properties> <cargo.logging>high</cargo.logging> <cargo.servlet.port>8080</cargo.servlet.port> </properties> </configuration> </configuration> <executions> <execution> <id>start-container</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> <goal>deploy</goal> </goals> <configuration> <wait>false</wait> <deployer> <deployables> <deployable> <location>${basedir}/target/${project.artifactId}-test.war</location> <type>war</type> <pingURL>http://localhost:8080/${project.artifactId}-test/index.html</pingURL> <pingTimeout>300000</pingTimeout> <properties> <context>${project.artifactId}-test</context> </properties> </deployable> </deployables> </deployer> </configuration> </execution> <execution> <id>stop-container</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> ... </plugins> ... </build> ...
Most of this is pretty self explanatory, I try to use parameters to configure as much as I can and try to maintain it in higher level POMs wherever appropriate. This is especially true for the tomcat URL which changes on a regular basis. The seem to post new releases and remove the older ones, and it can be a chore to keep up in multiple projects. You may want to look at the cargo plugin documentation, you can ignore some of what I'm doing above if you're project's default artifact (the one package creates) is a web-app.  So there you have it, eventually I got there after a lot of digging. I've been pretty brief in my explanations and have assumed a fairly good understanding of maven. if you have any questions by all means leave a comment and I'll do my best to make it clearer.
[[posterous-content:xEkrcgitujefewHaqcIv]]