2018-10-16に更新

mochaとPhantomJSでjavascriptのテスト

開発中のWEBサイトのjavascriptのテストをコンソールで自動化するシンプルなプロジェクトを作成した。

使い方だが

  1. dala00/test_by_phantomjsをクローン
  2. npm install
  3. npm test

でspecフォルダの全てのテストが走る。

ライブラリ

PhantomJS

画面表示のないブラウザ。これでコンソールでの自動化を実現。
ただし、PhantomJSを起動してテストを実行しなければならないため
その他のライブラリはrequireで読み込める事が条件。
色々調べた結果下記のライブラリに落ち着いた。

mocha

テストパッケージ。本当は使えないのだが、

feb0223/mocha-phantom

の偉業により使用可能に。

chai

アサーションライブラリ。多分他のでも大丈夫だと思う。

テストプログラム解説

specフォルダにサンプルでSampleSpec.jsを入れてあるので解説。

var webpage = require('webpage');
var page = webpage.create();

PhantomJSのオブジェクトを作成。これはPhantomJS起動でないとrequireできないので今回の構成に決まった。
起動方法はtest.jsを見れば書いてある。test.js内で全部のプログラムを起動しているだけ。

before(function(done) {
    // 指定したページをオープン
    page.open('http://url.for.test/', function(status) {
        if (status !== 'success') {
            console.log('error!');
            phantom.exit();
            return;
        }
        done();
    });
});

URLを開く。失敗したらphantom.exit()する。
とにかく終わるときはexitしないとプロセスが残ってプログラムが終了しないので注意。

it('Fade out', function(done) {
    var oldDisplay = page.evaluate(function() {
        var ret = $('#closePanel').css('display');
        $('#closeButton').trigger('click');
        return ret;
    });
    var display;
    wait.for(function() {
        display = page.evaluate(function() {
            return $('#closePanel').css('display');
        });
        return display != oldDisplay;
    }, function() {
        expect(display).to.not.equal(oldDisplay);
        done();
    });
});

実際のテスト部分。page.evaluate内は完全に別世界となる。
そこではブラウザ上のjavascriptを操作できる。
(むしろそれしかできない。スコープも関係ない)
return することでこっち側の世界に値を持ってこれる。

つまり上記は

  1. まず初期のdisplayの状態をoldDisplayに取得しつつ閉じるボタンもクリックしておく
  2. wait.forはひとつ目の関数がtrueになるまで待つ。displayの状態が変わるまで待つ。
    上手く動かない場合はタイムアウト(3つ目の引数指定可能)でもウェイト終了。
  3. wait.forのふたつ目の関数が実行されて終了。

wait.forはPhantomJSに入っていたサンプルのwaitforを改造しただけのもの。
setTimeoutだと動作が遅い場合テスト失敗になってしまうのでこの方法を採用。
他の類似ライブラリでもいいと思う。

specフォルダにファイルはいくらでも追加できるのでちょっとしたテストには充分。
ブラウザ側のjavascriptがそのまま使えるのでSelenium WebDriverより記述も簡単だと思う。
execしてstdoutを取得しているだけなのでtest.jsを改造すればテスト結果の集計なども可能なはず。

ツイッターでシェア
みんなに共有、忘れないようにメモ

だら@Crieit開発者

Crieitの開発者です。 Webエンジニアです(在宅)。大体10年ちょい。 記事でわかりにくいところがあればDMで質問していただくか、案件発注してください。 業務依頼、同業種の方からのコンタクトなどお気軽にご連絡ください。 業務経験有:PHP, MySQL, Laravel, React, Flutter, Vue.js, Node, RoR 趣味:Elixir, Phoenix, Nuxt, Express, GCP, AWS等色々 PHPフレームワークちいたんの作者

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント