アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

LocalKitを使っているなら自動テストも簡単。JavaScriptテストフレームワークまとめ

LocalKitを使うメリットの一つにテストフレームワークが容易に使えるようになるという点が挙げられます。そこで今回は開発したJavaScriptコードでユニットテストを実現するためのフレームワークを紹介します。



Jasmine: Behavior-Driven JavaScript





Jasmine



JasmineはRSecに似た記述のテスト文法をもったテストフレームワークとなっています。例えば次のように記述します。





describe("CallTracker", function() {
  it("tracks that it was called when executed", function() {
    var callTracker = new j$.CallTracker();

    expect(callTracker.any()).toBe(false);

    callTracker.track();

    expect(callTracker.any()).toBe(true);
  });

  it("tracks that number of times that it is executed", function() {
    var callTracker = new j$.CallTracker();

    expect(callTracker.count()).toEqual(0);

    callTracker.track();

    expect(callTracker.count()).toEqual(1);
  });
  :
});


expectで取得される値と期待される値とを比較する形になります。



QUnit





QUnit



QUnitは長く知られているユニットテストフレームワークになります。HTMLの結果画面を見たことがある方も多いのではないでしょうか。テストコードは次のように書きます。





QUnit.test("prettydate basics", function( assert ) {
  var now = "2008/01/28 22:25:00";
  assert.equal(prettyDate(now, "2008/01/28 22:24:30"), "just now");
  assert.equal(prettyDate(now, "2008/01/28 22:23:30"), "1 minute ago");
  :
});


元々jQueryから派生したツールと言うこともあり、jQuery必須となっています。



alexyoung/riotjs



riotjsはRubyのテストフレームワークRiotのJavaScript版です。テストは次のように記述します。





Riot.run(function() {
  context('basic riot functionality', function() {
    given('some simple equality tests', function() {
      asserts('a simple truth test should return true', true).isTrue();
      asserts('isNull is null', null).isNull();
    });

    given('another context', function() {
      asserts('equals should compare strings as expected', 'test string').equals('test string');
    });

    given('a context concerned with functions', function() {
      asserts('asserts() should allow functions to be compared', function() {
        return 'test string';
      }).equals('test string');
    });
  });

  given('yet another context', function() {
    asserts('equals should compare strings as expected', 'test string').equals('test string');
  });
});


ブラウザの他、RhinoやNodeでも動作します。



Unit testing framework for Javascript - Unit JS





Unit.js



Unit.jsもWebブラウザ、Nodeの両方で動作します。書き方が独特かも知れません。





// By example, provided by Express framework and other modules.
var req = {
  headers: {
    'content-type': 'application/json'
  }
};
test.object(obj).hasProperty('name');
test.object(obj).hasProperty('message', 'hello');
test.string(str).startsWith('Hello');
test.string(str).contains('world');
test.string(str).match(/[a-zA-Z]/);
test.value(req).hasHeader('content-type');
test.value(req).hasHeader('content-type', 'application/json');
// or
test.value(req).hasHeaderJson();


testというオブジェクトがあり、その下に変数の型を指定してプロパティや文字の長さ、正規表現などでチェックを行います。



nathansobo/screw-unit



Screw.UnitはBDDフレームワーク(ビヘイビア駆動開発)になります。RSpecに似た記述で、より仕様が分かりやすい文章を使ってテストを記述します。





describe("a nested describe", function() {
  var invocations = [];

  before(function() {
    invocations.push("before");
  });

  describe("a doubly nested describe", function() {
    before(function() {
      invocations.push('inner before');
    });

    it("runs befores in all ancestors prior to an it", function() {
      expect(invocations).to(equal, ["before", "inner before"]);
    });
  });
});


Protractor - end to end testing for AngularJS





Protractor



ProtractorはAngularJS用のE2Eテストフレームワークになります。専用ということもありますのでAngularJSアプリの場合はProtractorを使うのが良さそうです。





describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write first protractor test');

    // You wrote your first test, cross it off the list
    todoList.get(2).element(by.css('input')).click();
    var completedAmount = element.all(by.css('.done-true'));
    expect(completedAmount.count()).toEqual(2);
  });
});


Mocha - the fun, simple, flexible JavaScript test framework





Mocha



Mochaはシンプルなテストフレームワークになっています。ブラウザでもNodeでも動作します。コードはJasmineなどに近いものになります。





var assert = require("assert")
describe('Array', function() {
  describe('#indexOf()', function () {
    it('should return -1 when the value is not present', function () {
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
    });
  });
});





今回紹介したフレームワークはWebブラウザやNodeで実行するものが多くなっています。そのため、MonacaアプリのJavaScript実装部分においてユニットテストができるでしょう。



もしOnsen UIを使われているならばProtractorは良い選択肢になるかと思います。品質高いアプリを目指し、しっかりとテストを作り込んでください。