代々木で働く19歳エンジニアのブログ

思ったこととか、技術的なこと書きます。

Automated testing with mocha / mocha 触ってみた

install

Install with npm globally:

$ npm install --global mocha
npm install --save-dev mocha

mocha とは

Mocha is a feature-rich JavaScript test framework

テスト全体を取りまとめて管理したり、画面に表示したりするためのもの

chaiとの違い

chaiとは

Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

テスティングフレームワークと合わせて使うアサーションライブラリ。アサーションは、個々のテストの判定を行いその結果を返すための機能。

chaiとmochaの違いは、chaiアサーションのためのライブラリだけど、mochaはテスティングフレームワーク

development example

累乗(jsでいう**)の関数を開発する。

1, テストととして仕様を書く

describe("pow", function() {

  it("raises to n-th power", function() {
    assert.equal(pow(2, 3), 8);
  });

});
  • describe("title", function() { ... })

    • 仕様としての関数を書く
  • it("title", function() { ... })

  • assert.equal(value1, value2)

    • その実装が期待通り動いているか確認する

→ 落ちる

2, 実装を書く

function pow() {
  return 8; // :) we cheat!
}

→ 成功

3, usecaseを追加する

describe("pow", function() {

  it("raises to n-th power", function() {
    assert.equal(pow(2, 3), 8);
  });

+  it("3 raised to power 3 is 27", function() {
+    assert.equal(pow(3, 3), 27);
+  });

});

4, 2に戻る

function pow() {
-   return 8; // :) we cheat! 
+  let result = 1;
+
+  for (let i = 0; i < n; i++) {
+    result *= x;
+  }
+
+  return result;
}

5, 1→4を繰り返す。

Goal

<!DOCTYPE html>
<html>
<head>
  <!-- add mocha css, to show results -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
  <!-- add mocha framework code -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
  <script>
    mocha.setup('bdd'); // minimal setup
  </script>
  <!-- add chai -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
  <script>
    // chai has a lot of stuff, let's make assert global
    let assert = chai.assert;
  </script>
</head>

<body>

  <script>
    function pow(x, n) {
      if (n < 0) return NaN;
      if (Math.round(n) != n) return NaN;

      let result = 1;

      for (let i=0; i < n; i++) {
        result *= x;
      }
      return result;
    }
  </script>

  <!-- the script with tests (describe, it...) -->
  <script src="test.js"></script>

  <!-- the element with id="mocha" will contain test results -->
  <div id="mocha"></div>

  <!-- run tests! -->
  <script>
    mocha.run();
  </script>
</body>

</html>
describe("pow", function() {
  it ("for nagative in the result is NaN", function() {
    assert.isNaN(pow(2, -1));
  });

  it ("for no-integer n the result is NaN", function() {
    assert.isNaN(pow(2, 1.5));
  });

  describe("raises x to power n", function(){
    function makeTest(x) {
      let expected = x * x * x;
      it (`${x} in the power 3 is expected`, function(){
        assert.equal(pow(x, 3), expected)
      });
    }

    for (let x = 1; x <= 5; x++) {
      makeTest(x);
    }
  });
});

まとめ

  • Behavior Driven Development (BDD) では、実装 (implementation) の前に仕様 (specification) が来る。そして最後に仕様とコードが揃う。

    • 仕様(テスト)を書く→落ちる→その落ちた仕様の実装 というのをやっていく。
  • よくテストされたコードは、良い設計につながる

    • 何をやっているかわかりやすい、入力と出力が明確

感想

  • mocha & chai は、js 版rspecみたいな感じかな。
  • test(仕様)→実装 という開発手法は始めてだったので新鮮だった。ただちょっと開発が遅くなりそうだと思った。
  • もとが英語記事なので、日本語の語の定義が難しかった。

reference from