WebdriverIO + power-assert でe2eテストをgeneratorで書いてみる


WebdriverIOは、ES6 generators (yield)を利用してテストが書けるので、power-assertと組み合わせてテストを書いてみた。

準備

gulpで環境構築するサンプルを作ったのでgit clone...

$ git clone [email protected]:yoshi6jp/webdriverio-power-assert-sample.git
$ cd webdriverio-power-assert-sample/
$ npm install

とりあえず、実行してみる

$ npm test

> [email protected] test webdriverio-power-assert-sample
> gulp

[07:00:45] Requiring external module coffee-script/register
[07:00:46] Using gulpfile webdriverio-power-assert-sample/gulpfile.coffee
[07:00:46] Starting 'selenium-install'...
[07:03:51] Finished 'selenium-install' after 3.08 min
[07:03:51] Starting 'selenium'...
[07:03:51] Finished 'selenium' after 592 ms
[07:03:51] Starting 'webdriver'...
[07:03:51] spawn wdio with these attributes:
 webdriverio-power-assert-sample/wdio.conf.js

․․․․

4 passing (25.60s)


[07:04:18] wdio testrunner finished with exit code 0
[07:04:18] Finished 'webdriver' after 26 s
[07:04:18] Starting 'default'...
[07:04:18] Finished 'default' after 579 μs

  • Selenium Webdriverのダウンロード、インストール、起動もgulpでやってます
  • firefoxが起動して、テストが実行されるはず...

解説

generatorの例

  • ほぼ、WebdriverIOのサンプルそのままですが。。。
var assert = require('power-assert');
// :
describe('js test case', function() {
  before(function(){
    browser.url('http://webdriver.io');
  })
  it('generator', function* () {
    // function* でgeneratorの宣言

    var title = yield browser.getTitle();   
    //yieldでtitleの値を取得

    assert(/WebdriverIO/.test(title) == true);
  });
  // :    
});
  • power-assertなのでエラー時もきれいに表示(assert(title == "ng")を追加して実行)
AssertionError:   # test/specs/case1.js:15

  assert(title == "ng")
         |     |       
         |     false   
         "WebdriverIO - Selenium 2.0 javascript bindings for nodejs"

Custom Commandsを使ってみる

  • 独自のコマンドをbrowserオブジェクトに追加して利用できる

promise版

browser.addCommand("getUrlAndTitle", function() {
    return this.url().then(function(urlResult) {
        return this.getTitle().then(function(titleResult) {
            return { url: urlResult.value, title: titleResult };
        });
    });
});

generator版

// この記述だとエラーになる
browser.addCommand("getUrlAndTitle", function* () {
  var urlResult = yield this.url();
  var titleResult = yield this.getTitle();
  return { url: urlResult.value, title: titleResult };
});
  • addCommandは、promiseしか対応していないので、単純にfunction*でgeneratorを書くとエラーに...

カスタムコマンドでもgeneratorを使いたいので、coを使って解決!

 解決方法

var co = require('co');
browser.addCommand("getUrlAndTitle", co.wrap(function* () {
  var urlResult = yield this.url();
  var titleResult = yield this.getTitle();
  return { url: urlResult.value, title: titleResult };
}));
  • co.wrapを使うとgeneratorpromiseに変換できる
var assert = require('power-assert');
var co = require('co');
browser.addCommand("getUrlAndTitle", co.wrap(function* () {
  var urlResult = yield this.url();
  var titleResult = yield this.getTitle();
  return { url: urlResult.value, title: titleResult };
}));
describe('js test case', function() {
  before(function(){
    browser.url('http://webdriver.io');
  })
  it('custom command', function* (){
    var urlAndTitle = yield browser.getUrlAndTitle();
    // カスタムコマンドを実行してyieldで値を取得

    assert(/WebdriverIO/.test(urlAndTitle.title) == true);
    assert(urlAndTitle.url == 'http://webdriver.io/');
  });
});

coffeescriptでも書いてみる

assert = require 'power-assert'
co = require 'co'
browser.addCommand "getUrlAndTitleCS", co.wrap ->
  urlResult = yield this.url()
  titleResult = yield this.getTitle()
  url: urlResult.value, title: titleResult

describe 'cs test case', ->
  before ->
    browser.url 'http://webdriver.io'

  it 'generator', ->
    title = yield browser.getTitle()
    assert /WebdriverIO/.test(title) == true

  it 'custom command', ->
    urlAndTitle = yield browser.getUrlAndTitleCS()
    assert /WebdriverIO/.test(urlAndTitle.title) == true
    assert urlAndTitle.url == 'http://webdriver.io/'

  • coffeescriptの場合、->演算子の中にyieldがあるとgeneratorと解釈してくれるので、少し便利!

他のブラウザでテストする場合

weio.conf.jsを編集することで可能

   capabilities: [{
        browserName: 'firefox' 
        // -> 'chrome' or 'internet explorer', etc
    }],
  • 他にも色々とカスタマイズできる