views:

1766

answers:

4

I want completely automated integration testing for a Maven project. The integration tests require that an external (platform-dependent) program is started before running. Ideally, the external program would be killed after the unit tests are finished, but is not necessary.

Is there a Maven plugin to accomplish this? Other ideas?

+1  A: 

You could use the antrun plugin. Inside you would use ant's exec apply task.

Something like this.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.2</version>
    <executions>
      <execution>
        <phase> <!-- a lifecycle phase --> </phase>
        <configuration>

          <tasks>
            <apply os="unix" executable="cmd">
              <arg value="/c"/>
              <arg value="ant.bat"/>
              <arg value="-p"/>
            </apply>
            <apply os="windows" executable="cmd.exe">
              <arg value="/c"/>
              <arg value="ant.bat"/>
              <arg value="-p"/>
            </apply>
          </tasks>

        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Ant support os specific commands of course through the condition task.

sblundy
An interesting, non-intuitive use of the antrun plugin. I was hoping for something cleaner, but this just might work for me.
flicken
Maven tends toward plugins for specific tasks. What commands are you trying to run, they might have plugins.
sblundy
Commands are project-specific executables, so a generic 'execute' plugin would be necessary.
flicken
+1  A: 

I'm currently working on a more specific plugin that could easily be "degraded" to be a simple external task executer but ... there are quite a few other things to consider.

  1. How do you know the process has actually started?
  2. What do you do with the return code?
  3. How do you make sure the executor plugin runs first (bind it to the test-compile phase)?

I'm sure there would be more if I actually started developing the plugin, but is there really a need for a generic executer?

UPDATE:

I guess there is ... there's an excellent set of Maven plugins at CodeHaus. Here's the one you want: http://mojo.codehaus.org/exec-maven-plugin/.

Steve Moyer
A: 

Do you want to start an application server ? Have a look at Cargo and its Maven plugin.

Tom
+1  A: 

The cargo maven plugin is a good way to go if you're doing servlet development and want to deploy the resulting WAR for integration testing.

When I do this myself, I often set up a multi-module project (although that's not strictly nessecarily) and encapsulate all the integration testing into that one module. I then enable the module with profiles (or not) so that it's not blocking the immediate "yeah, I know I broke it" builds.

Here's the pom from that functional test module - make of it what you will:

<?xml version="1.0"?><project>
  <parent>
    <artifactId>maven-example</artifactId>
    <groupId>com.jheck</groupId>
    <version>1.5.0.4-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.jheck.example</groupId>
  <artifactId>functional-test</artifactId>
  <name>Example Functional Test</name>
  <packaging>pom</packaging>

  <dependencies>
    <dependency>
      <groupId>com.jheck.example</groupId>
      <artifactId>example-war</artifactId>
      <type>war</type>
      <scope>provided</scope>
      <version>LATEST</version>
    </dependency>
    <dependency>
      <groupId>httpunit</groupId>
      <artifactId>httpunit</artifactId>
      <version>1.6.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <executions>
          <execution>
            <phase>integration-test</phase>
            <goals>
              <goal>test</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>0.3</version>
        <configuration>
          <wait>false</wait> <!-- don't pause on launching tomcat... -->
          <container>
            <containerId>tomcat5x</containerId>
            <log>${project.build.directory}/cargo.log</log>
            <zipUrlInstaller>
              <!--
              <url>http://www.apache.org/dist/tomcat/tomcat-5/v5.0.30/bin/jakarta-tomcat-5.0.30.zip&lt;/url&gt;
               -->
               <!-- better be using Java 1.5... -->
              <url>http://www.apache.org/dist/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.zip&lt;/url&gt;

              <installDir>${installDir}</installDir>
            </zipUrlInstaller>
          </container>
          <configuration>
            <!-- where the running instance will be deployed for testing -->
            <home>${project.build.directory}/tomcat5x/container</home>
          </configuration>
        </configuration>

        <executions>
          <execution>
            <id>start-container</id>
            <phase>pre-integration-test</phase>
            <goals>
              <goal>start</goal>
              <goal>deploy</goal>
            </goals>
            <configuration>
              <deployer>
                <deployables>
                  <deployable>
                    <groupId>com.jheck.example</groupId>
                    <artifactId>example-war</artifactId>
                    <type>war</type>
                    <!-- <properties>
                      <plan>${basedir}/src/deployment/geronima.plan.xml</plan>
                    </properties> -->
                    <pingURL>http://localhost:8080/example-war&lt;/pingURL&gt;
                  </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>

</project>
heckj