LoginSignup
31
27

More than 5 years have passed since last update.

JsTestDriver使い方メモ

Last updated at Posted at 2013-09-22

JsTestDriver の使い方をメモする。
JsTestDriver とは、 Google が開発してるオープンソースの JavaScript 用テスティングフレームワークのこと。

環境

OS

Windows7 64bit

Java

1.7.0_25

JsTestDriver

1.3.5

JsTestDriver のインストール

ここ から JsTestDriver-x.x.x.jar をダウンロードして任意のフォルダに配置する。
仮に jar を配置したフォルダのパスを %JSTESTDRIVER_HOME% とする。

テストを実行する

JsTestDriver でテストするときの手順はおおまかには以下の通り。

  1. JsTestDriver サーバを起動する
  2. テストしたいブラウザを JsTestDriver サーバに接続する
  3. テストを実行する

JsTestDriver サーバを起動する

コマンドプロンプトを開き、以下のコマンドを実行する。

サーバの起動
>java -jar %JSTESTDRIVER_HOME%\JsTestDriver-x.x.x.jar --port 4224

サーバが 4224 ポートで起動する(4224 ポートは JsTestDriver を使うときの慣例らしい)。

テストしたいブラウザを JsTestDriver サーバに接続する

とりあえず Chrome で接続する。
Chrome を起動し、 http://localhost:4224 にアクセスする。

Chromeでアクセスした様子

テストする時のページのDTD を「移行型」と「厳密型」のどちらにするかを選択する。
選択すると、以下のページに移動する。ブラウザの準備はこれで OK。

ブラウザで接続

テストを実行する

フォルダ構成

フォルダ構成
D:\tmp\JsTestDriver
│  jsTestDriver.conf
├─src
│      TestTarget.js
└─test
        TestTargetTest.js

各ファイルの内容

src/TestTarget.js
function targetMethod(x, y) {
    return x + y;
}
test/TestTargetTest.js
TestCase('TestTarget Test', {
    'test targetMethod': function() {
        // setup
        var expected = 51;

        // exercise
        var actual = targetMethod(11, 40);

        // verify
        assertEquals(expected, actual);
    }
});
jsTestDriver.conf
server: http://localhost:4224

load:
    - src/*.js
    - test/*.js

実行方法

コマンドプロンプトを開き、 jsTestDriver.conf のあるフォルダに移動して次のコマンドを実行する。
jsTestDriver.conf があるフォルダまでのパスに日本語が含まれるとエラーになる。

テストの実行
>java -jar %JSTESTDRIVER_HOME%\JsTestDriver-x.x.x.jar --tests all
テストの実行結果
setting runnermode QUIET
.
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (0.00 ms)
  Chrome 29.0.1547.76 Windows: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (0.00 ms)

注意点

テスト関数は、名前が test で始まっている必要がある。

テスト関数の名前のルール
TestCase('TestTarget Test', {
    // 実行される
    'test function': function() {
        jstestdriver.console.log('test function');
    },

    // 実行されない
    'not test function': function() {
        jstestdriver.console.log('not test function');
    }
});
実行結果
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (1.00 ms)
Chrome 29.0.1547.76 Windows: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (1.00 ms)

TestTarget Test.test function passed (1.00 ms)
[LOG] test function

テスト関数名には日本語が使えるが、実行時に文字化けする

日本語は基本文字化けする
TestCase('TestTarget Test', {
    'test 日本語': function() {
        jstestdriver.console.log('test 日本語');
    }
});
実行結果
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (0.00 ms)
Chrome 29.0.1547.76 Windows: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (0.00 ms)

TestTarget Test.test ??{?? passed (0.00 ms)
[LOG] test ??{??

実行はできるけど、文字化けしてしまう。
テスト名は日本語で書きたいなぁ。。。

その他使い方

コンソール出力

console はブラウザによっては対応していないものがあるので、 JsTestDriver を使うときは JsTestDriver が提供してるコンソール出力用 API を使うのが良い。
具体的には、 jstestdriver.console というオブジェクトを使う。

loginfodebug といった関数が用意されてる。

コンソール出力
TestCase('TestTarget Test', {
    'test console': function() {
        var console = jstestdriver.console;

        console.log('log message');
        console.debug('debug message');
        console.info('info message');
        console.warn('warn message');
        console.error('error message');
    }
});
実行結果
[LOG] log message
[DEBUG] debug message
[INFO] info message
[WARN] warn message
[ERROR] error message

C の printf 的な使い方もできる。

フォーマット
TestCase('TestTarget Test', {
    'test console': function() {
        var string = 'string message';
        var obj = {
            string: 'Name',
            num   : 10,
            bool  : true,
            und   : undefined,
            nul   : null,
            func  : function() {
                alert('hoge');
            }
        };

        var console = jstestdriver.console;

        console.log('string = %s', string);
        console.log('obj = %o', obj);
    }
});
実行結果
[LOG] string = string message
[LOG] obj = {"string":"Name","num":10,"bool":true,"nul":null}

%s で文字列形式、 %o でオブジェクトを JSON に変換した形式で出力できる(undefined と関数は出力されない)。

事前処理・事後処理を実装する

JUnit の setUptearDown メソッドに該当するもの。
ずばりその名前で関数を定義すれば、各テストの前後で実行される。

事前・事後処理
TestCase('TestTarget Test', {
    setUp: function() {
        log('setUp');
    },

    tearDown: function() {
        log('tearDown');
    },

    'test 1': function() {
        log('test 1');
    },

    'test 2': function() {
        log('test 2');
    }
});

function log(msg) {
    jstestdriver.console.log(msg);
}
実行結果
TestTarget Test.test 1 passed (0.00 ms)
[LOG] setUp
[LOG] test 1
[LOG] tearDown

TestTarget Test.test 2 passed (0.00 ms)
[LOG] setUp
[LOG] test 2
[LOG] tearDown

各テストメソッドごとに、 setUp() 関数と tearDown() 関数が呼ばれる。

各テスト関数で共通して使用する値を用意する

各テストで共通して使用したい値がある場合は、 setUp() 関数内で this にプロパティを追加すればいい。

各テストで共通して使用する値の参照
var cons = jstestdriver.console

TestCase('TestTarget Test', {
    setUp: function() {
        this.value = 'common value';
    },

    'test 1': function() {
        cons.log('test 1 : this.value = %s', this.value);
    },

    'test 2': function() {
        cons.log('test 2 : this.value = %s', this.value);
    }
});
実行結果
TestTarget Test.test 1 passed (0.00 ms)
[LOG] test 1 : this.value = common value

TestTarget Test.test 2 passed (0.00 ms)
[LOG] test 2 : this.value = common value

1つの js ファイルに複数の TestCase を書く

JUnit4 の Enclosed みたいなイメージ。

複数のTestCase
var cons = jstestdriver.console;

TestCase('TestCase 1', {
    'test 1': function() {
        cons.log('test 1');
    }
});

TestCase('TestCase 2', {
    'test 2': function() {
        cons.log('test 2');
    }
});
実行結果
Total 2 tests (Passed: 2; Fails: 0; Errors: 0) (1.00 ms)
Chrome 29.0.1547.76 Windows: Run 2 tests (Passed: 2; Fails: 0; Errors 0) (1.00 ms)

TestCase 1.test 1 passed (1.00 ms)
[LOG] test 1

TestCase 2.test 2 passed (0.00 ms)
[LOG] test 2

問題なく動く。事前処理が同じものでまとめるとコードが見やすくなるかな。

テスト用の DOM を用意する

テストコード中に特殊なコメントを記述することで、テストでのみ使える DOM を用意することができる。

DOM オブジェクトを作成する

DOMオブジェクトの作成
TestCase('TestCase 1', {
    'test': function() {
        /*:DOC dom = <input value="test-value" />*/

        var value = this.dom.getAttribute('value')
        jstestdriver.console.log('dom.value = %s', value);
    }
});
実行結果
[LOG] dom.value = test-value
DOMオブジェクトを定義するときの書式
/*:DOC <変数名> = <HTMLタグ>*/

テスト実行時にコメント行を通過すると、以後 this.<変数名><HTMLタグ> に指定したタグの DOM オブジェクトを取得できるようになる。

コメント行の前では DOM オブジェクトは取得できない

コメント行が処理される前だと、 DOM オブジェクトは生成されないので注意。

コメント行の前ではDOMオブジェクトはまだできていない
TestCase('TestCase 1', {
    'test': function() {
        jstestdriver.console.log('dom = %s', this.dom);

        /*:DOC dom = <input />*/
    }
});
実行結果
[LOG] dom = undefined

各テスト関数で生成した DOM オブジェクトはその関数内でのみ有効

各テスト関数内で生成された DOM は、その関数内でのみ使用可能で、他のテスト関数からは参照できない。

他のテスト関数で生成されたDOMオブジェクトは参照できない
var cons = jstestdriver.console;

TestCase('TestCase 1', {
    'test': function() {
        cons.info('test1');
        /*:DOC dom = <input />*/
        cons.log('dom = %s', this.dom);
    },

    'test2': function() {
        cons.info('test2');
        cons.log('dom = %s', this.dom);
    }
});
実行結果
TestCase 1.test passed (0.00 ms)
[INFO] test1
[LOG] dom = [object HTMLInputElement]

TestCase 1.test2 passed (0.00 ms)
[INFO] test2
[LOG] dom = undefined

各テスト関数から参照できる DOM オブジェクトを用意する

各テスト関数から共通で参照したい DOM オブジェクトがある場合は、 setUp() 関数にコメントを書けばいい。

setUp関数でDOMオブジェクトを宣言する
var cons = jstestdriver.console;

TestCase('TestCase', {
    setUp: function() {
        /*:DOC dom = <input value="common-value" />*/
    },

    'test1': function() {
        cons.info('test 1');
        cons.log(this.dom.getAttribute('value'));
    },

    'test2': function() {
        cons.info('test 2');
        cons.log(this.dom.getAttribute('value'));
    }
});
実行結果
TestCase.test1 passed (0.00 ms)
[INFO] test 1
[LOG] common-value

TestCase.test2 passed (0.00 ms)
[INFO] test 2
[LOG] common-value

複数の DOM を作成可能

1つのコメントの中で、複数のタグを記述できる。

複数のDOMを作成
TestCase('TestCase', {
    'test': function() {
        /*:DOC dom = <input value="test-value-1" /><input value="test-value-2" />*/

        var children = this.dom.childNodes;

        for (var i=0; i<children.length; i++) {
            jstestdriver.console.log('childNodes[%d].value = %s', i, children[i].getAttribute('value'));
        }
    }
});
実行結果
[LOG] childNodes[0].value = test-value-1
[LOG] childNodes[1].value = test-value-2

ブラウザにDOMを追加する

ブラウザにDOMを追加する
TestCase('TestCase', {
    'test': function() {
        /*:DOC += <input id="test-dom" value="test-value" />*/

        var value = document.getElementById('test-dom').getAttribute('value')
        jstestdriver.console.log('value = %s', value);
    }
});
実行結果
[LOG] value = test-value
ブラウザにDOMを追加する場合のコメントの書式
/*:DOC += <HTMLタグ>*/

他のテスト関数から参照できないなどの動作は DOM オブジェクトを作成する場合と同じ。

参考

31
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
27