vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

【Ruby Gem】JasmineでJSテスト 1

前回に引き続きJasmineと戯れてみたメモ。

思ったより苦戦したので、とりあえず現状をまとめます。

なおテスト対象のJavascriptここ参照(コードはそろそろGithubにでも上げることにします)。

javascriptSpec.js

describe("javascript.js", function() {
  var fileModel;
  beforeEach(function () {
    fileModel = new FileModel();
  });
  it('Get default HTML templates by TabNum & ContentNum', function () {
    spyOn($, "ajax");
    getHtml(0, 0);
    expect($.ajax.calls.mostRecent().args[0]['url']).toEqual('/html/0.html');
  });
  it('Get default model datas', function () {
    expect(fileModel.get('page')).toBe(0);
    expect(fileModel.get('content')).toBe(0);
    expect(fileModel.get('file')).toBe('');
  });
  it('Get ContentFileCollection', function () {
    expect(ContentFileCollection.length).toBeGreaterThan(0);
    var fileName = ContentFileCollection.findWhere({page: 0, content: 0}).get('file');
    expect(fileName).toEqual('0.html');
  });
});

テストコードは以下の形式で記述していき、「expect(ターゲットとなるデータ).to〜(比較するデータ)」の形で確認を行います。

describe('Specの説明文', function() {
  it('実行するテストコードの説明文', function() {
    // 実行するテストコード
  });
});

また、テスト開始前に実行しておきたい処理は「beforeEach」に、終了後に実行したい処理は「afterEach」で実行します。

上記のコードにはテストが3種類含まれており、内容は以下のとおりです。 1. Ajax通信を(擬似的に)行い、アクセスしたURLを取得し、想定通りの内容かを確認する 2. [Backbone] Modelデータを新規作成して、デフォルト値が正しいかを確認する 3. [Backbone] Collectionにデータが正しくセットされていることを確認する

1. Ajax通信を(擬似的に)行い、アクセスしたURLを取得し、想定通りの内容かを確認する

非同期でHTMLファイルを取得する処理のテストのため、Spy機能を使用します。
Spy機能は指定したメソッドに使用することができ、今回はAjaxの処理に対して実施しています。

SpyOnでオブジェクトを作成したあとAjaxの処理を行い、その後「$.ajax.calls.mostRecent()」で直近に実行された処理のデータを取得しています。

「.toEqual(比較データ)」で、両者が等しいかを確認します。
また等しくないことを確認するには、「.not.toEqual(比較データ)」とします。

Spy機能については、その他Methodの戻り値を指定できたり、通信成功時の処理の確認などができるようですが(以下の最初の回答参照)、使い道がまだよく理解できていないため、特に取り入れていません。 * javascript - How do I verify jQuery AJAX events with Jasmine? - Stack Overflow

※なお、上記で使われている「spyOn($, "ajax").andCallFake(〜」は、Jasmine2.0以降「spyOn($, "ajax").and.callFake(〜」に変更されています。

2. [Backbone] Modelデータを新規作成して、デフォルト値が正しいかを確認する

こちらは1よりシンプルで、newでBackbone.Modelを新規作成して、Modelが持つ要素やデフォルト値を確認しているだけです。

注意点としては、テスト対象のデータがグローバル化されていないと、Specファイルからアクセスができないことです。
そのため3.のBackbone.Collectionも含めて元のjavascriptを変更しました(これ以外に方法があれば訂正します)。

before

(function () {
  var intTabNum = 0;
  var aryTabName = ["tab_label_0", "tab_label_1", "tab_label_2", "tab_label_3", "tab_label_4"]
  var intRightTabNum = 2;
  var intLeftTabNum = 0;
  var DEFAULT_RIGHT_TAB_NUM = 2;
  var FileModel = Backbone.Model.extend({
    defaults: {
      page: 0,
      content: 0,
      file: ''
    }
  });
  var FileCollection = Backbone.Collection.extend({
    model: FileModel
  });
  var ContentFileCollection = new FileCollection([
      {page: 0, content: 0, file: '0.html'},
      {page: 0, content: 1, file: '1.html'},
      {page: 1, content: 0, file: '0.html'},
      {page: 1, content: 1, file: '1.html'},
      {page: 2, content: 0, file: '0.html'},
      {page: 2, content: 1, file: '1.html'},
      {page: 3, content: 0, file: '0.html'},
      {page: 3, content: 1, file: '1.html'},
      {page: 4, content: 0, file: '0.html'},
      {page: 4, content: 1, file: '1.html'}]);
〜省略〜

after

var FileModel = Backbone.Model.extend({
  defaults: {
    page: 0,
    content: 0,
    file: ''
  }
});
var FileCollection = Backbone.Collection.extend({
  model: FileModel
});
var ContentFileCollection = new FileCollection([
    {page: 0, content: 0, file: '0.html'},
    {page: 0, content: 1, file: '1.html'},
    {page: 1, content: 0, file: '0.html'},
    {page: 1, content: 1, file: '1.html'},
    {page: 2, content: 0, file: '0.html'},
    {page: 2, content: 1, file: '1.html'},
    {page: 3, content: 0, file: '0.html'},
    {page: 3, content: 1, file: '1.html'},
    {page: 4, content: 0, file: '0.html'},
    {page: 4, content: 1, file: '1.html'}]);
(function () {
  var intTabNum = 0;
  var aryTabName = ["tab_label_0", "tab_label_1", "tab_label_2", "tab_label_3", "tab_label_4"]
  var intRightTabNum = 2;
  var intLeftTabNum = 0;
  var DEFAULT_RIGHT_TAB_NUM = 2;
〜省略〜

課題

Ajaxで、通信の結果として得られるデータの検証

HTML形式のデータを取得してページ表示を行うため、取得したデータがHTMLのタグを含むか、などのテストをしたいのですが、 今のところSpecファイルからデータを取得する方法わからず苦戦しています。

普段rakeではなくrackupでサーバーを起動するためか、単純に設定漏れなのかAjaxで取得するファイルにアクセスできないため、このあたりも解決したいところ。

あと、今回は実装できていませんが、以前問題と感じていたBackbone.Viewから呼び出すメソッド名が存在しなかった場合に、 何もエラーが出ない、という問題もSpy機能を使う解決できそうです。

次回はそのあたりに挑戦してみる予定です。

参考