Maven

aguizar edited this page May 29, 2011 · 40 revisions

The Cuke4Duke Maven plugins lets you run Cucumber features with Maven. You’ll need Maven 2.2.1 or newer to make sure classpaths work properly. All of Cuke4Duke’s examples have a pom.xml that you can use for inspiration, but we’ll walk you through the details on this page.

POM
cuke
To make Cucumber work with your Maven project you must add the following to your pom.xml file:

<repositories>
    <repository>
      <id>codehaus</id>
      <url>http://repository.codehaus.org</url>
    </repository>
    <repository>
      <id>cukes</id>
      <url>http://cukes.info/maven</url>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
      <id>cukes</id>
      <url>http://cukes.info/maven</url>
    </pluginRepository>
</pluginRepositories>

<properties>
    <cuke4duke.version>0.4.4</cuke4duke.version>

    <!-- Behind a proxy? -->
    <!-- see http://wiki.github.com/aslakhellesoy/cuke4duke/installing-gems -->
    <!--  and http://github.com/aslakhellesoy/cuke4duke/issues/issue/36 -->
    <!--http.proxy>http://your.proxy:port</http.proxy-->
</properties>

<dependencies>
    <dependency>
      <groupId>cuke4duke</groupId>
      <artifactId>cuke4duke</artifactId>
      <version>${cuke4duke.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.picocontainer</groupId>
      <artifactId>picocontainer</artifactId>
      <version>2.8.3</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
      <plugin>
        <groupId>cuke4duke</groupId>
        <artifactId>cuke4duke-maven-plugin</artifactId>
        <version>${cuke4duke.version}</version>
        <configuration>
          <jvmArgs>
            <jvmArg>
              -Dcuke4duke.objectFactory=cuke4duke.internal.jvmclass.PicoFactory
            </jvmArg>
          </jvmArgs>
          <cucumberArgs>
            <cucumberArg>${project.basedir}/target/test-classes</cucumberArg>
          </cucumberArgs>
          <gems>
            <gem>install cuke4duke --version ${cuke4duke.version}</gem>
             <!-- Behind a proxy? -->
             <!--gem>install cuke4duke --version ${cuke4duke.version} --http-proxy ${http.proxy}</gem-->
          </gems>
        </configuration>
        <executions>
          <execution>
            <id>run-features</id>
            <phase>integration-test</phase>
            <goals>
              <goal>cucumber</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
</build>

See below for more explanations.

Behind a proxy?

No worries. Rubygems has a --http-proxy option you can pass to it.
Cf. Installing gems and issue-36

Repositories

Tell Maven where to download cuke4duke and jruby:

<repositories>
  <repository>
    <id>codehaus</id>
    <url>http://repository.codehaus.org</url>
  </repository>
  <repository>
    <id>cukes</id>
    <url>http://cukes.info/maven</url>
  </repository>
</repositories>

<pluginRepositories>
  <pluginRepository>
    <id>cukes</id>
    <url>http://cukes.info/maven</url>
  </pluginRepository>
</pluginRepositories>

Properties

To share some properties like cuke4duke version:

<properties>
    <cuke4duke.version>YOUR_CUKE4DUKE_VERSION</cuke4duke.version>

    <!-- Behind a proxy? -->
    <!-- see http://wiki.github.com/aslakhellesoy/cuke4duke/installing-gems -->
    <!--  and http://github.com/aslakhellesoy/cuke4duke/issues/issue/36 -->
    <!--http.proxy>http://your.proxy:port</http.proxy-->
</properties>

Dependencies

Tell Maven that you’re using Cuke4Duke and PicoContainer so that Maven will add them to your Classpath. (If you’re using Spring you can specify that instead of PicoContainer). We also add a dependency to JUnit because our Java step definitions will use it.

<dependencies>
  <dependency>
    <groupId>cuke4duke</groupId>
    <artifactId>cuke4duke</artifactId>
    <version>${cuke4duke.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.picocontainer</groupId>
    <artifactId>picocontainer</artifactId>
    <version>2.8.3</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.7</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Execution

Tell Maven to run your Cucumber features during the integration-test phase:

<build>
  <plugins>
    <plugin>
      <groupId>cuke4duke</groupId>
      <artifactId>cuke4duke-maven-plugin</artifactId>
      <version>${cuke4duke.version}</version>
      <configuration>
        <jvmArgs>
          <jvmArg>
            -Dcuke4duke.objectFactory=cuke4duke.internal.jvmclass.PicoFactory
          </jvmArg>
        </jvmArgs>
        <cucumberArgs>
          <cucumberArg>${project.basedir}/target/test-classes</cucumberArg>
        </cucumberArgs>
        <gems>
          <gem>install cuke4duke --version ${cuke4duke.version}</gem>
           <!-- Behind a proxy? -->
           <!--gem>install cuke4duke --version ${cuke4duke.version} --http-proxy ${http.proxy}</gem-->
        </gems>
      </configuration>
      <executions>
        <execution>
          <id>run-features</id>
          <phase>integration-test</phase>
          <goals>
            <goal>cucumber</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Bootstrapping

Before you can use Cuke4Duke with Maven, you must install the Cucumber Ruby gem (and all of its dependent Ruby gems) in JRuby:

mvn -Dcucumber.installGems=true integration-test

File structure

Your application’s Cucumber Feature files should be placed in a directory named features – just like on any other Cucumber project. This is where the Cuke4Duke Maven plugin will expect them to be.

Java step definitions should be placed where you would normally place JUnit tests – in src/test/java. If you’re using Scala, place them in src/test/scala. Make sure you also pass --require target/test-classes to cucumber in your pom.xml.

If you’re using a language that doesn’t have to be precompiled (such as Ruby, Groovy, Javascript, Clojure or Ioke), just put step definitions under features/step_definitions. In this case you don’t have to use the --require option.

Running your features

Now that you have configured your POM and created some features and step definitions, try running your features:

mvn integration-test

If you just want to save time and run without compiling anything (for example if you only modified a .feature file, or an interpreted step definition file):

mvn cuke4duke:cucumber

Passing Cucumber command line options from your command line.

You can’t pass Cucumber command line options (such as --tags @foo) straight to mvn, but you can sneak them through with a system property. For example:

mvn cuke4duke:cucumber -DcukeArgs="--tags @foo"

—and pick them up inside your POM:

<cucumberArg>${cukeArgs}</cucumberArg>

Command line execution

Now that you have local JRuby installation underneath your local Maven repository you can use the Command Line interface if you want, using ~/.m2/repository/.jruby/bin/cuke4duke.

Avoiding out of memory exceptions

If you encounter OutOfMemory or PermGen exceptions when running your scenarios you can tweak the maximum available memory by adding the following JVM args to pom.xml. Both options are shown here, but they can be used independently.

<plugin>
  <groupId>cuke4duke</groupId>
    <artifactId>cuke4duke-maven-plugin</artifactId>
      <configuration>
        ...
        <jvmArgs>
          <jvmArg>-Xmx1024m</jvmArg>
          <jvmArg>-XX:MaxPermSize=256m</jvmArg>
        </jvmArgs>
      </configuration>
      ...