読者です 読者をやめる 読者になる 読者になる

望月いちろうのREADME.md

書き溜めておいた技術記事や旅行記のバックアップです。

Mochaを使ってNode.jsのテストを自動化する

Node.js

前回はChaiを利用してNode.jsのTDD, BDDの導入法について紹介しました。

今回はMochaを利用して一連のテストを自動化する方法を紹介したいと思います。

Mochaの公式はこれです。

Mocha - the fun, simple, flexible JavaScript test framework

使い方

Mochaは通常グローバルにインストールします。

$ sudo npm install mocha -g

プロジェクトのホームディレクトリにtestフォルダを作成します。

この中にtest.jsを作成します。この中にテストのロジックを記述することになります。

package.jsonに追記

コマンド1つでmochaを使ったテストが実行可能になる様にpackage.jsonを編集します。 この中でmochaを開発時に限定して利用する様に設定を追加します。

また

$ npm test

でテストが実行できる様に設定を行います。 “scripts"に"test"を追記します。

"script":{
  ...
  "test":"mocha"
}
"devDependencies":{
  ...
  "chai": "*",
  "mocha": "*"
},

次はtest/test.jsの中身を編集します。

mochaで基本となるのはdescribe, itとその中のコールバック関数です。

describe('/*基本となるブロック*/', ()=> {
    it('/* 各テストの説明をここに書く */', (done)=>{
    /** 
    *  この中にchaiのテスト関数を記述する
    */
    });
});

実際には1つの大きなブロックとなるdescribe関数を用意した上で、その中に複数のdescribe関数を配置してテストをすることが多いようです。

describe('/*基本となるブロック*/', ()=> {

   describe('/*基本となるブロック*/', ()=> {
        it('/* 各テストの説明をここに書く */', (done)=>{
    /** 
    *  この中にchaiのテスト関数を記述する
    */
         });
    });

   describe('/*基本となるブロック*/', ()=> {
        it('/* 各テストの説明をここに書く */', (done)=>{
    /** 
    *  この中にchaiのテスト関数を記述する
    */
         });
    });

});

Expressでの利用例をここに示します。

Expressで画像を配信、投稿するAPIを整備したとします。この API に対するBDDを設定したいとします。

サーバーサイド(Express)はこのようになっています。

...

router.get('/:_id',(res,req,next)=>{
 
    Image.get(req.param.id,(err,image)=>{
        if(err) throws err;
        return res.send(image);
    });
});

router.post('/upload',(res,req,next)=>{
 
    Image.post(req.body.image, (err, result)=>{
        if(err) throws err;
        return res.send(true);
    });
});

このとき各ルーティングに期待する振る舞いを考えます。 つまり、

  • POST /upload - 画像を投稿する
  • GET /:id - IDに応じて画像を取得する

このときの各テストのロジックは以下のようになります。

  describe('#id()', function() {
    it('get without error', function(done) {
      chai.request('http://localhost:3000')
      .get('/schostakovich')
      .end((err, res)=>{ 
         expect(err).to.be.null;
         expect(res).to.have.status(200);
         done();
      });
    });
  });

  describe('#upload()', function() {
    it('save without error', function(done) {

        chai.request("http://localhost:3000")
        .post("/image")
.attach('image', fs.readFileSync('./test/image/schostakovich.jpg'), 'schostakovich.jpg')
        .end((err,res)=>{
            expect(err).to.be.null;
            expect(res).to.have.status(200);
            done();
        });
      
    });
  });


```

実際にテストを実行してみましょう

$ mocha

失敗した場合

  User
    #id()
      1) get without error
double callback!
    #upload()
      2) save without error
double callback!
  0 passing (53ms)
  2 failing

無事テストが通過したら以下のようになります。

$ mocha 
  User
    #id()
      ✓ get without error (79ms)
    #upload()
      ✓ save without error (783ms)


  2 passing (873ms)

いかがでしょうか?

このように複数のパスに対するテストを一括で実行可能なのがmochaの優れた特徴です。