cucumberjsを使ってみる

  • 0
    いいね
  • 0
    コメント
    • Gherkin syntaxを使いたい
    • AWS Lambdaで使いたい
    • 知ってる言語ベースだと更に助かる

    上記の理由から、nodeで動くcucumber-jsを使ってみました。

    参考にした記事

    http://qiita.com/p-baleine@github/items/5e6cd1ed12e31bf7edc2
    https://github.com/cucumber/cucumber-js/blob/master/docs/nodejs_example.md

    ライブラリインストール

    $ npm install -S express multiline
    $ npm install --save-dev cucumber@latest selenium-webdriver@3.0.1 chromedriver@2.25.1
    

    とりあえずこんな感じに。

    package.json
    {
      "name": "cucumnerjs-example",
      "version": "1.0.0",
      "description": "example",
      "main": "index.js",
      "scripts": {
        "test": "./node_modules/.bin/cucumber.js",
        "start": "node index.js"
      },
      "author": "hideokamoto",
      "license": "MIT",
      "dependencies": {
        "express": "^4.14.0",
        "multiline": "^1.0.2"
      },
      "devDependencies": {
        "chromedriver": "^2.25.1",
        "cucumber": "^2.0.0-rc.6",
        "selenium-webdriver": "^3.0.1"
      }
    }
    

    テスト用アプリの作成

    テストするにはテスト対象を作らないとです。
    ということで参考記事よろしくnodeで動くwebページを1つ用意します。

    src/index.js
    const express = require('express')
    const multiline = require('multiline')
    const app = express()
    
    app.get('/', (req, res) => {
        res.send(multiline( () => {/*
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
      </head>
      <body>
        <p>Cucumber-js example</p>
      </body>
    </html>
      */}))
    })
    
    module.exports = app
    
    
    index.js
    const app = require('./src/index')
    
    app.listen(3000, () => {
        console.log('port 3000')
    })
    

    アプリはnpm startで起動します。

    $ npm start
    
    > cucumnerjs-example@1.0.0 start /develop/node/cucumberjs
    > node index.js
    
    port 3000
    

    テスト時に使うので、そのままにしておきましょう。

    cucumberjsでのテスト準備

    cucumberjs自体はfeatureディレクトリさえあれば実行可能です。

    $ mkdir features
    $ npm test
    
    > cucumnerjs-example@1.0.0 test /develop/node/cucumberjs
    > cucumber.js 
    
    0 scenarios
    0 steps
    0m00.000s
    

    もっとも、テストファイルが存在しないのでただ実行しただけですが。

    Gherkinでテストを書く

    とりあえずテストを書いておきましょう。

    features/example.feature
    Feature: Example feature
      As a user of Cucumber.js
      I want to have example application
      So that I can concentrate on building awesome applications
    
      Scenario: I am on the TopPage
        Given I am on the TopPage
        Then I should see "Cucumber-js example"
    

    Featureの下3行はテスト概要などです。
    Scenario以下が実際に実行するテスト内容となります。

    今回は

    • Given I am on the TopPage
    • Then I should see "Cucumber-js example"

    の2つをテストするということですね。

    この状態でテストを実行すると、以下のように「対応するコードがない」というエラーが出てきます。

    Feature: Example feature
    
        As a user of Cucumber.js
        I want to have documentation on Cucumber
        So that I can concentrate on building awesome applications
    
      Scenario: I am on the TopPage
      ? Given I am on the TopPage
      ? Then I should see "Cucumber-js example"
    
    Warnings:
    
    1) Scenario: I am on the TopPage - features/documentation.feature:6
       Step: Given I am on the TopPage - features/documentation.feature:7
       Message:
         Undefined. Implement with the following snippet:
    
           Given('I am on the TopPage', function (callback) {
             // Write code here that turns the phrase above into concrete actions
             callback(null, 'pending');
           });
    
    2) Scenario: I am on the TopPage - features/documentation.feature:6
       Step: Then I should see "Cucumber-js example" - features/documentation.feature:8
       Message:
         Undefined. Implement with the following snippet:
    
           Then('I should see {arg1:stringInDoubleQuotes}', function (arg1, callback) {
             // Write code here that turns the phrase above into concrete actions
             callback(null, 'pending');
           });
    
    1 scenario (1 undefined)
    2 steps (2 undefined)
    0m00.000s
    npm ERR! Test failed.  See above for more details.
    

    「こういう風にコード書いてくれ」という指示も出してくれるので、このあたりを参考にコードを書いておきましょう。

    ドライバーの設定

    先にテストを実行するためのwebドライバを設定します。

    features/support/world.js
    require('chromedriver')
    var seleniumWebdriver = require('selenium-webdriver');
    var {defineSupportCode} = require('cucumber');
    
    function CustomWorld() {
      this.driver = new seleniumWebdriver.Builder()
        .forBrowser('chrome')
        .build();
    }
    
    defineSupportCode(function({setWorldConstructor}) {
      setWorldConstructor(CustomWorld)
    })
    

    step_definitionsの設定

    続いてGherkinに対応するstep_definitionsを記述します。

    features/step_definitions/browser_steps.js
    var seleniumWebdriver = require('selenium-webdriver');
    var {defineSupportCode} = require('cucumber');
    
    defineSupportCode(function({Given, Then}) {
        Given('I am on the TopPage', function () {
          return this.driver.get('http://localhost:3000');
        });
        Then('I should see {stringInDoubleQuotes}', function (text) {
            const xpath = "//*[contains(text(),'" + text + "')]"
            const condition = seleniumWebdriver.until.elementLocated({xpath: xpath})
    
            return this.driver.wait(condition, 10000)
        });
    });
    

    hookの設定

    features/support/hooks.jsへ、scenarioの前後に実行したいコードを書くことができます。

    var {defineSupportCode} = require('cucumber');
    
    defineSupportCode(function({After}) {
      After(function() {
        return this.driver.quit();
      });
    });
    

    テストを実行

    お待たせしました。いよいよテスト実行の瞬間です。
    事前にnpm startlocalhost:3000にアクセスできることを確認しておきましょう。

    $ npm test
    
    > cucumnerjs-example@1.0.0 test /develop/node/cucumberjs
    > cucumber.js
    
    Feature: Example feature
    
        As a user of Cucumber.js
        I want to have documentation on Cucumber
        So that I can concentrate on building awesome applications
    
      Scenario: I am on the TopPage
      ✔ Given I am on the TopPage
      ✔ Then I should see "Cucumber-js example"
    
    1 scenario (1 passed)
    2 steps (2 passed)
    0m01.406s
    

    成功しました。

    テストを失敗させる

    せっかくなので、テスト失敗のケースも見ます。
    src/index.js内のコンテンツを書き換えて、npm startを再実行します。

    src/index.js
    const express = require('express')
    const multiline = require('multiline')
    const app = express()
    
    app.get('/', (req, res) => {
        res.send(multiline( () => {/*
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
      </head>
      <body>
        <p>Fail test pattern</p>
      </body>
    </html>
      */}))
    })
    
    module.exports = app
    
    

    テストを実行してみましょう。

    $ npm test
    
    > cucumnerjs-example@1.0.0 test /develop/node/cucumberjs
    > cucumber.js
    
    Feature: Example feature
    
        As a user of Cucumber.js
        I want to have documentation on Cucumber
        So that I can concentrate on building awesome applications
    
      Scenario: I am on the TopPage
      ✔ Given I am on the TopPage
      ✖ Then I should see "Cucumber-js example"
    
    Failures:
    
    1) Scenario: I am on the TopPage - features/example.feature:6
       Step: Then I should see "Cucumber-js example" - features/example.feature:8
       Step Definition: features/step_definitions/browser_steps.js:8
       Message:
         Error: function timed out after 5000 milliseconds
             at Timeout.<anonymous> (/develop/node/cucumberjs/node_modules/cucumber/lib/user_code_runner.js:91:22)
             at ontimeout (timers.js:365:14)
             at tryOnTimeout (timers.js:237:5)
             at Timer.listOnTimeout (timers.js:207:5)
    
    1 scenario (1 failed)
    2 steps (1 failed, 1 passed)
    0m06.392s
    npm ERR! Test failed.  See above for more details.
    

    失敗しました。

    使ってみて

    step_definitionsを自前で書かないといけないのがちょっとツラいなという感じがあります。
    BehatであればMinkExtensionを入れるだけでそこそこ使える感じになっていたという印象がありますので。

    ・・・なんてことを脳内でボヤいていたら、ありました。
    https://www.npmjs.com/package/cucumber-mink

    次回はこれを使ってみようと思います。