Goal
To run Cucumber specifications via Maven.tl;dr
A maven plug-in for running Cucumber features via Cucumber-JVM is available on github and will be a helpful resource for following this article. There is also a maven archetype for generating a Cucumber-JVM project. Acceptance tests for the dropbox-maven-plugin and jacoco-scala-maven-plugin both run using this plugin and can be used as templates for your own specifications. The interesting technologies showcased include Cucumber-JVM and JRuby.The Project
Suppose our product owner would like to specify the behavior of our product in a way that can be verified automatically and continuously, for example, using Gherkin. Now suppose we would like to configure a Maven build system to run these acceptance tests.Using Ant Runner
The maven-antrun-plugin can often be the fallback when there is no maven plug-in for a specific purpose. Indeed there are instructions and examples of using the maven-antrun-plugin to spawn the command-line versions of both JRuby and Cucumber-JVM for initializing a Cucumber project, installing its required bundles and executing its specifications.A project with a Gemfile in its root, features in its src/test/features directory and Ruby step definitions in its src/test/features/step_definitions directory can use a pom configuration like this to install and run its acceptance tests.
The project layout
my-cucumber-jvm-specifications
.
|____Gemfile
|____pom.xml
| src
| | test
| | | features
| | |____my.feature
| | | | step_definitions
| | | |____my_steps.rb
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-from-ant</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>cucumber-jvm-from-ant</name>
<properties>
<cucumber-jvm-version>1.1.5</cucumber-jvm-version>
<features-directory>src/test/features</features-directory>
<gems-directory>${project.build.directory}/gems</gems-directory>
</properties>
<dependencies>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-jruby</artifactId>
<version>${cucumber-jvm-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>${basedir}/${features-directory}</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>generate-test-resources</phase>
<configuration>
<target>
<sequential>
<echo message="Installing bundler gem" />
<java jar="${maven.dependency.org.jruby.jruby-complete.jar.path}"
fork="true" failonerror="true" maxmemory="256m"
newenvironment="true">
<arg value="-S" />
<arg value="gem" />
<arg value="install" />
<arg value="bundler" />
<arg value="-i" />
<arg value="${gems-directory}" />
<arg value="--no-ri" />
<arg value="--no-rdoc" />
</java>
<echo message="Doing bundle install" />
<java jar="${maven.dependency.org.jruby.jruby-complete.jar.path}"
fork="true" failonerror="true" maxmemory="512m"
newenvironment="true">
<env key="GEM_HOME" path="${gems-directory}" />
<arg value="-S" />
<arg value="${gems-directory}/bin/bundle" />
<arg value="install" />
<arg value="--gemfile=${basedir}/Gemfile" />
</java>
</sequential>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<phase>test</phase>
<id>run-cucumbers</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo message="Running Cucumber Ruby Features" />
<java fork="true" classname="cucumber.api.cli.Main"
classpathref="maven.test.classpath" failonerror="true">
<env key="GEM_HOME" path="${gems-directory}" />
<env key="RUBY_VERSION" value="2.0" />
<arg value="-f" />
<arg value="pretty" />
<arg value="--glue" />
<arg value="${features-directory}" />
<arg value="${features-directory}" />
</java>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-from-ant</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>cucumber-jvm-from-ant</name>
<properties>
<cucumber-jvm-version>1.1.5</cucumber-jvm-version>
<features-directory>src/test/features</features-directory>
<gems-directory>${project.build.directory}/gems</gems-directory>
</properties>
<dependencies>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-jruby</artifactId>
<version>${cucumber-jvm-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>${basedir}/${features-directory}</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>generate-test-resources</phase>
<configuration>
<target>
<sequential>
<echo message="Installing bundler gem" />
<java jar="${maven.dependency.org.jruby.jruby-complete.jar.path}"
fork="true" failonerror="true" maxmemory="256m"
newenvironment="true">
<arg value="-S" />
<arg value="gem" />
<arg value="install" />
<arg value="bundler" />
<arg value="-i" />
<arg value="${gems-directory}" />
<arg value="--no-ri" />
<arg value="--no-rdoc" />
</java>
<echo message="Doing bundle install" />
<java jar="${maven.dependency.org.jruby.jruby-complete.jar.path}"
fork="true" failonerror="true" maxmemory="512m"
newenvironment="true">
<env key="GEM_HOME" path="${gems-directory}" />
<arg value="-S" />
<arg value="${gems-directory}/bin/bundle" />
<arg value="install" />
<arg value="--gemfile=${basedir}/Gemfile" />
</java>
</sequential>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<phase>test</phase>
<id>run-cucumbers</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo message="Running Cucumber Ruby Features" />
<java fork="true" classname="cucumber.api.cli.Main"
classpathref="maven.test.classpath" failonerror="true">
<env key="GEM_HOME" path="${gems-directory}" />
<env key="RUBY_VERSION" value="2.0" />
<arg value="-f" />
<arg value="pretty" />
<arg value="--glue" />
<arg value="${features-directory}" />
<arg value="${features-directory}" />
</java>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Using the JRuby and Cucumber-JVM Plug-ins
This pom forks new processes for installing bundler, installing the bundles required by the tests and running the tests themselves. The jruby-maven-plugin and cucumber-jvm-maven-plugin can be configured to run specifications without relying on the maven-antrun-plugin to execute new processes. Configuration is similar to the command-line JRuby and Cucumber-JVM clients, and in fact, each plug-in can take a raw CLI configuration if the built-in goals are not sufficient.Given the same project layout as above, this pom will perform the identical steps in the same Maven process.
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-from-maven</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>cucumber-jvm-from-maven</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gems-directory>${project.build.directory}/gems</gems-directory>
<jruby-version>1.7.4</jruby-version>
<cucumber-jvm-version>1.1.5</cucumber-jvm-version>
</properties>
<profiles>
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<runCucumbers>true</runCucumbers>
</properties>
</profile>
<profile>
<id>skip-tests</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>skipTests</name>
<value>true</value>
</property>
</activation>
<properties>
<runCucumbers>false</runCucumbers>
</properties>
</profile>
<profile>
<id>run-tests</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>runCucumbers</name>
<value>true</value>
</property>
</activation>
<build>
<testResources>
<testResource>
<directory>src/test/features</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>timezra.maven</groupId>
<artifactId>jruby-maven-plugin</artifactId>
<version>${jruby-version}</version>
<executions>
<execution>
<id>install-bundles</id>
<phase>pre-integration-test</phase>
<goals>
<goal>gem-install</goal>
<goal>bundle-install</goal>
</goals>
<configuration>
<gem_home>${gems-directory}</gem_home>
<gem>bundler</gem>
<gemfile>${project.basedir}/Gemfile</gemfile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-maven-plugin</artifactId>
<version>${cucumber-jvm-version}</version>
<<dependencies>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>${jruby-version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>run-cucumbers</id>
<phase>integration-test</phase>
<goals>
<goal>jruby</goal>
</goals>
<configuration>
<gem_home>${gems-directory}</gem_home>
<feature>${project.build.testOutputDirectory}</feature>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<pluginRepositories>
<pluginRepository>
<id>tims-repo</id>
<url>http://timezra.github.com/maven/releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-from-maven</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>cucumber-jvm-from-maven</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gems-directory>${project.build.directory}/gems</gems-directory>
<jruby-version>1.7.4</jruby-version>
<cucumber-jvm-version>1.1.5</cucumber-jvm-version>
</properties>
<profiles>
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<runCucumbers>true</runCucumbers>
</properties>
</profile>
<profile>
<id>skip-tests</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>skipTests</name>
<value>true</value>
</property>
</activation>
<properties>
<runCucumbers>false</runCucumbers>
</properties>
</profile>
<profile>
<id>run-tests</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>runCucumbers</name>
<value>true</value>
</property>
</activation>
<build>
<testResources>
<testResource>
<directory>src/test/features</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>timezra.maven</groupId>
<artifactId>jruby-maven-plugin</artifactId>
<version>${jruby-version}</version>
<executions>
<execution>
<id>install-bundles</id>
<phase>pre-integration-test</phase>
<goals>
<goal>gem-install</goal>
<goal>bundle-install</goal>
</goals>
<configuration>
<gem_home>${gems-directory}</gem_home>
<gem>bundler</gem>
<gemfile>${project.basedir}/Gemfile</gemfile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>timezra.maven</groupId>
<artifactId>cucumber-jvm-maven-plugin</artifactId>
<version>${cucumber-jvm-version}</version>
<<dependencies>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>${jruby-version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>run-cucumbers</id>
<phase>integration-test</phase>
<goals>
<goal>jruby</goal>
</goals>
<configuration>
<gem_home>${gems-directory}</gem_home>
<feature>${project.build.testOutputDirectory}</feature>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<pluginRepositories>
<pluginRepository>
<id>tims-repo</id>
<url>http://timezra.github.com/maven/releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
Using the Cucumber-JVM Archetype
There is a Maven archetype for this type of acceptance testing project that will help you get started. With a single command, the boilerplate project layout and pom configuration will be generated automatically so that you can start writing specifications and step definitions right away.$ mvn archetype:generate -DarchetypeCatalog=http://timezra.github.com/maven/releases/archetypes -Dfilter=timezra.maven:cucumber-jvm-archetype
fill in the groupId, artifactId, version and feature information
cd to the new project
$ unset GEM_PATH GEM_HOME RUBY_VERSION
$ mvn verify
No comments:
Post a Comment