Vue + E2Eテスト


はじめに

前回、「Vue + 単体テスト」という題でVueの単体テストについて書きました。その続きになります。この記事ではE2Eテストについて書いていきます。

E2Eテストとは

通称End to Endテスト。システム全体を通してテストをおこないます。よく例にあげられるのはログインページです。

(システム全体【ログインまで】の流れ)
1. ログインページを開く
2. メールアドレスを入力する
3. パスワードを入力する
4. ログインボタンをクリックする
5. メールアドレスとパスワードの判定を行う
6. トップページへ遷移する

前回の単体テストは、個々の機能のみで判定して成功か失敗かを返していたが、E2Eテストではその単体テストを集めてその一連の流れでうまくいっているか否かを判定します。特徴は以下の通りです。

  • 上位レベル
  • フィードバックが遅い
  • 実行が遅い
  • 壊れやすい

実はこれ、単体テストと全く真逆の特徴です。
単体テストは1つ1つの機能で判定してるので実行が早く、フィードバックがしやすいのですが、E2Eテストは一連の流れの処理ができたうえで始めるため、実行が遅くかつフィードバックの修正次第ではまた違うエラーを引き起こす可能性もあるので壊れやすいです。

例で例えられるのが以下のピラミッドです。
上に行くほど、遅く、コストが高いと言われます。

テスト実行環境

今回も前回同様でVueを用いてE2Eテストを実行していきましょう。
NightWatchというE2E用のフレームワークを用いておこないます。

Vueプロジェクト構成でtest/e2eがあると思います。そのディレクトリにcustom_commandsフォルダを作り、そこにカスタムコマンドを作っていきます。

実践してみた。

それではVue.jsでE2Eテスト書いていきましょう。先ほどのcustom_commandsフォルダにパスを通しましょう。環境構築の部分を書いていきます。

test/e2e/specs/nightwatch.js
require('babel-register')
var config = require('../../config')

// http://nightwatchjs.org/gettingstarted#settings-file
module.exports = {
  src_folders: ['test/e2e/specs'],
  output_folder: 'test/e2e/reports',
  custom_assertions_path: ['test/e2e/custom-assertions'],
  custom_commands_path: ['test/e2e/custom-command'], //パスを通す

またDOM操作でイベントをトリガーできるように設定するJSファイルやinput要素へのキーボード入力をエミュレーションできるように設定するファイルを設定しましょう。

//DOMのトリガー受付
exports.command = function (selector, event, keyCode) {
    return this.execute(function (selector, event, keyCode) {
        var e = document.createEvent('HTMLEvents')
        e.initEvent(event, true, true)
        if (keyCode) {
            e.keyCode = keyCode
        }
        document.querySelector(selector).dispatchEvent(e)
    }, [selector, event, keyCode])
}
//input要素のキーボードイベントを受け入れる
exports.command = function (selector, value) {
    return this.clearValue(selector)
        .setBalue(selector, value)
        .triggaer(selector, 'keyup', 13)
}

あとは実行したいテストを書いていくだけです。
test/e2e/specsのフォルダに対象のファイルを書いていきましょう。
G例としてoogleにアクセスしていろいろ操作するサンプルを見てみましょう。

url(string) .. 参照したいWebサイト等を指定
waitForElementVisible ... 他のコマンドまたはアサートが実行される前に要素がページに表示されるのを所定のミリ秒単位で待つ

などなど色々あります。
詳しくはNightWatchのAPIを参照してください。

example.js
module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .assert.title('Google')
      .assert.visible('input[type=text]')
      .setValue('input[type=text]', 'rembrandt van rijn')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('ol#rso li:first-child',
        'Rembrandt - Wikipedia')
      .end();
  }
};

あとは実行しましょう。

$ npm run e2e

まとめ

最近はテストの重要性がよくわかっていた気がします。