読者です 読者をやめる 読者になる 読者になる

Cucumber を Groovy で実行2 - Maven, Gradle

はじめに

前回 に続き、今回は Maven と Gradle を使って cucumber-jvm を実行してみます。

フィーチャやステップ定義は前回と同じものをそのまま使いますが、common.groovy の @Grab('org.seleniumhq.selenium:selenium-java:2.33.0') は不要なのでコメントアウトしておきます。

common.groovy
package sample

this.metaClass.mixin(cucumber.api.groovy.Hooks)
this.metaClass.mixin(cucumber.api.groovy.EN)
・・・
// Maven や Gradle で依存モジュールを解決するため @Grab の設定は不要
//@Grab('org.seleniumhq.selenium:selenium-java:2.33.0')
import org.openqa.selenium.*
・・・

ソースは http://github.com/fits/try_samples/tree/master/blog/20130725/

Maven で実行

それでは Maven で実行してみます。

JUnit 上で実行するので @RunWith アノテーションに Cucumber を指定した下記のようなクラスを作成しておきます。

また、実行対象のタグや結果出力フォーマットなどを指定する方法としては、後述のシステムプロパティ cucumber.options を使用する方法と下記のコメント行のように @Cucumber.Options を使用する方法があります。

RunTest.groovy (JUnit 実行用クラス)
package sample

import cucumber.api.junit.Cucumber
import org.junit.runner.RunWith

@RunWith(Cucumber.class)
// 下記のようにアノテーションでオプション指定する事も可能
// @Cucumber.Options(tags = "@current")
public class RunTest {
}

ビルド定義ファイル pom.xml は下記のようになります。 groovy-eclipse-compiler プラグインを使って Groovy のソースをビルドするようにしました。

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>fits.sample</groupId>
  <artifactId>gitblit_cucumber_sample</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0</version>
  <name>gitblit cucumber sample</name>
  <properties>
    <groovyVersion>2.1.6</groovyVersion>
    <groovyEclipseCompilerVersion>2.7.0-01</groovyEclipseCompilerVersion>
    <cucumberVersion>1.1.3</cucumberVersion>
    <junitVersion>4.11</junitVersion>
    <seleniumVersion>2.33.0</seleniumVersion>
  </properties>
  <dependencies>
    <dependency>
      <groupId>info.cukes</groupId>
      <artifactId>cucumber-groovy</artifactId>
      <version>${cucumberVersion}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>info.cukes</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>${cucumberVersion}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junitVersion}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>${groovyVersion}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${seleniumVersion}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <compilerId>groovy-eclipse-compiler</compilerId>
          <encoding>UTF-8</encoding>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-compiler</artifactId>
            <version>${groovyEclipseCompilerVersion}</version>
          </dependency>
        </dependencies>
      </plugin>
      <plugin>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-eclipse-compiler</artifactId>
        <version>${groovyEclipseCompilerVersion}</version>
        <extensions>true</extensions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <configuration>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

実行

maven test で実行します。

実行例1
> mvn test
・・・
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running sample.RunTest

Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 22.268 sec

Results :

Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
・・・

cucumber.options システムプロパティでタグを指定するには下記のようにします。

実行例2 (@current タグのみ実行)
> mvn test -Dcucumber.options="-t @current"
・・・
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running sample.RunTest

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.548 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
・・・

ファイル構成

ディレクトリ・ファイル構成は下記のようになっています。

  • src/test/groovy
    • common.groovy
    • login.groovy
    • repository.groovy
    • RunTest.groovy
  • src/test/resources
    • sample
      • login.feature
      • repository.feature
  • pom.xml

ステップ定義のパッケージ名 (今回は sample) に基づいて、クラスパスからフィーチャファイルを探索するようなので、今回のフィーチャファイルは src/test/resources/sample へ配置する必要がありました。

Gradle で実行

次は Gradle で実行してみます。

  • Gradle 1.6
  • Gradle 1.7 RC1

Maven で実行する際に用意した RunTest.groovy (JUnit で実行するためのクラス)はそのまま使用します。

ビルド定義ファイルは以下のようになります。

build.gradle
apply plugin: 'groovy'

project.ext {
    groovyVersion = '2.1.6'
    cucumberVersion = '1.1.3'
    junitVersion = '4.11'
    seleniumVersion = '2.33.0'
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile "org.codehaus.groovy:groovy:${project.groovyVersion}"

    testCompile "info.cukes:cucumber-groovy:${project.cucumberVersion}"
    testCompile "info.cukes:cucumber-junit:${project.cucumberVersion}"

    testCompile "junit:junit:${project.junitVersion}"

    testCompile "org.seleniumhq.selenium:selenium-java:${project.seleniumVersion}"
}

test {
    // test でシステムプロパティを使用するための設定
    systemProperties = System.properties

    /* Gradle 1.7 でテスト結果の XML 出力を無効化するための設定
    reports.html.enabled = false
    reports.junitXml.enabled = false
    */
}

gradle test 時にシステムプロパティの値を参照させるには "test { systemProperties = System.properties }" の設定が必要となるようです。

実行

gradle test で実行します。

実行例1
> gradle test
・・・

ここで、Windows 上で実行すると下記のようなエラーが発生しテストに失敗します。(テスト自体は成功しています)

Windows 上で実行した場合のエラー
> gradle test
・・・
:test FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.
> Could not write XML test results for シナリオ: ログイン失敗 to file ・・・\build\test-results\TEST-シナリオ: ログイン失敗.xml.
・・・

これは Windows でファイル名に使えない文字 ":" を含んだファイル (上記では "TEST-シナリオ: ログイン失敗.xml") を出力しようとして失敗する事が原因です。

具体的には、org.gradle.api.internal.tasks.testing.junit.result.Binary2JUnitXmlReportGenerator.generate() メソッド内で TestClassResult.getClassName() の戻り値をそのまま出力ファイル名として使っている点に問題があるように思います。(Windows 環境は考慮されていないのかもしれませんが)

この問題を回避するために reports.junitXml.enabled = false 等の設定(Gradle 1.7 用、1.6 では使えない)でテスト結果 XML ファイル出力を無効化する方法があります。(根本的な解決ではありませんが)

cucumber.options システムプロパティを使ってタグを指定するには下記のようにします。(Maven と同様)

実行例2 (@current タグのみ実行)
> gradle test -Dcucumber.options="-t @current"
・・・

ファイル構成

ディレクトリ・ファイル構成は基本的に Maven と同じです。

  • src/test/groovy
    • common.groovy
    • login.groovy
    • repository.groovy
    • RunTest.groovy
  • src/test/resources
    • sample
      • login.feature
      • repository.feature
  • build.gradle