Mocha と Chai を使用した Node.js コードのテスト

概要

単体テストの作成は、初心者もベテラン エンジニアも同様に、開発の後の段階で一般的に後回しにするものですが、安定した堅牢なソフトウェア開発の鍵となります。

の基本的な前提 テスト駆動開発 (TDD) コーディングを開始する前であっても、テストを書いています。 これは素晴らしい目標ですが、その原則に従おうとすると、多くの規律と計画が必要になります。 このプロセス全体をより簡単にするために、次のような使いやすく強力なテストおよびアサーション フレームワークに頼ることができます。 モカ & チャイ.

この記事では、まずこれら XNUMX つのライブラリを紹介し、次にそれらを組み合わせて使用​​して、読み取り可能で機能的な単体テストをすばやく作成する方法を示します。

チャイ

Chai は、両方を提供するアサーション ライブラリです。 BDD (ビヘイビア駆動型開発) & TDD(テスト駆動開発) コードをテストするためのプログラミングのスタイルであり、テストを整理できるテスト ライブラリと組み合わせることが意図されています。 モカと組み合わせるのが一般的です。

XNUMX つの主要な API があります。

  • should
  • expect
  • assert

var.should.equal(var2)


expect.var.to.be.equal(var2)


assert.equal(var1, var2)

この記事では、Chai の BDD スタイルに焦点を当てます。 expect ただし、自分の直感に従って他のインターフェイス/スタイルを使用してもまったく問題ありません。 の assert インターフェイスは、一般的な TDD アサーション フレームワークに最もよく似ています。

expect 非常に自然な言語 API を使用してアサーションを記述します。これにより、テストの記述が容易になり、後で改善することができます。 これは、getter を連鎖させてアサーションを作成および実行することで実現され、要件をコードに変換しやすくなります。

let user = {name: 'Scott'};


expect(user).to.have.property('name');

注: アサーションを自然言語で読んで、何が起こっているのかを理解する方法がわかりますか? これは、Chai のようなアサーション ライブラリを使用する主な利点の XNUMX つです。

これらのゲッターのその他の例は次のとおりです。

  • to
  • be
  • is
  • and
  • has
  • have

これらのゲッターのかなりの数を連鎖させて、次のようなアサーション メソッドで使用できます。 true, ok, exist, empty 複雑なアサーションを XNUMX 行で作成するには:

"use strict";

const expect = require('chai').expect;


expect({}).to.exist;
expect(26).to.equal(26);
expect(false).to.be.false;
expect('hello').to.be.string;


expect([1, 2, 3]).to.not.be.empty;


expect([1, 2, 3]).to.have.length.of.at.least(3);

注: 利用可能なメソッドの完全なリストを見つけることができます こちら.

利用可能なリストを確認することもできます プラグイン チャイに。 これらにより、より複雑な機能のテストがはるかに簡単になります。

取る チャイ http たとえば、これはサーバー ルートのテストに役立つプラグインです。

"use strict";

const chai = require('chai');
const chaiHttp = require('chai-http');

chai.use(chaiHttp);

chai.request(app)
    .put('/api/auth')
    .send({username: '[email protected]', password: 'abc123'})
    .end(function(err, res) {
        expect(err).to.be.null;
        expect(res).to.have.status(200);
    });

Mocha を使用したテスト ケースの整理 – describe() と it()

Mocha は Node のテスト フレームワークであり、非同期 (または同期) コードをシリアルに実行する柔軟性を提供します。 キャッチされなかった例外は、それがスローされたテスト ケースと一緒に表示されるため、何が失敗したのか、その理由を簡単に特定できます。

Mocha をグローバルにインストールすることをお勧めします。

$ npm install mocha -g

グローバル インストールにする必要があります。 mocha コマンドは、ローカル ディレクトリでプロジェクトのテストを実行するために使用されます。

このコードは何をしますか?

it() X を返す必要があります。 it() テストケースを定義し、Mocha はそれぞれを実行します it() 単体テストとして。 複数の単体テストを整理するには、次のことができます。 describe() 共通の機能であり、Mocha テストを構造化します。

これはおそらく、具体的な例で最もよく説明されています。

"use strict";
const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });
    });
});

describe() メソッド、定義した テスト名 #abs(). 名前で個別にテストを実行することもできます。これについては後で説明します。

注: Mocha テストでは、その必要はありません require() Mocha メソッドのいずれか。 これらのメソッドは、 mocha

これらのテストを実行するには、ファイルを保存して、 mocha コマンド:

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given number 


  1 passing (9ms)

出力は、実行されたテストとその結果の内訳です。 ネストされた describe() 呼び出しは結果出力に引き継がれます。 特定のメソッドまたは機能のすべてのテストを入れ子にしておくと便利です。

これらのメソッドは、Mocha テスト フレームワークの基礎です。 それらを使用して、好きなようにテストを作成および整理します。 次のセクションで、この一例を見ていきます。

Mocha と Chai でテストを書く

プロジェクト内でテストを整理するための推奨される方法は、それらすべてを独自に配置することです /test ディレクトリ。 デフォルトでは、Mocha はグロブを使用して単体テストをチェックします。 ./test/*.js & ./test/*.coffee. そこから、を呼び出すファイルをロードして実行します。 describe() 方法。

ベストプラクティス、業界で認められた標準、および含まれているチートシートを含む、Gitを学習するための実践的で実用的なガイドを確認してください。 グーグルGitコマンドを停止し、実際に 学ぶ それ!

テストファイルにサフィックスを付けるのが一般的です .test.js Mocha テストを含むソース ファイルの場合:

├── package.json
├── lib
│   ├── db.js
│   ├── models.js
│   └── util.js
└── test
    ├── db.test.js
    ├── models.test.js
    ├── util.test.js
    └── util.js

util.js セクションに test ディレクトリには単体テストは含まれず、テストに役立つユーティリティ関数のみが含まれます。

Note: どのような構造でも使用できます。単体テストは自動的に選択されます。

実際にテストを書くことになると、 describe() メソッド。 機能、機能、ファイル、またはその他の任意のレベルで整理できます。 たとえば、関数レベルでの動作を記述するために編成されたテスト ファイルは次のようになります。

"use strict";

const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });

        it('should return positive value of given positive number', function() {
            expect(Math.abs(3)).to.be.equal(3);
        });

        it('should return 0 given 0', function() {
            expect(Math.abs(0)).to.be.equal(0);
        });
    });
});

テストを実行すると、次の出力が得られます。

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 


  3 passing (11ms)

さらに拡張すると、XNUMX つのファイルに複数のメソッドのテストを含めることさえできます。 この場合、メソッドは Math オブジェクト:

"use strict";

const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });

        it('should return positive value of given positive number', function() {
            expect(Math.abs(3)).to.be.equal(3);
        });

        it('should return 0 given 0', function() {
            expect(Math.abs(0)).to.be.equal(0);
        });
    });

    describe('#sqrt()', function() {
        it('should return the square root of a given positive number', function() {
            expect(Math.sqrt(25)).to.be.equal(5);
        });

        it('should return NaN for a given negative number', function() {
            expect(Math.sqrt(-9)).to.be.NaN;
        });

        it('should return 0 given 0', function() {
            expect(Math.sqrt(0)).to.be.equal(0);
        });
    });
});

結果は次のとおりです。

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  6 passing (10ms)

Mocha フック – before()、after()、beforeEach()、afterEach()

確かに、ほとんどの単体テストはこれほど単純ではありません。 多くの場合、データベースやその他の外部リソース (またはそれらのモック/スタブ) など、テストを実行するために他のリソースが必要になるでしょう。 これを設定するには、次の XNUMX つ以上を使用できます。 モカフック メソッド:

  • before(): 指定されたブロック内のすべてのテストの前に実行されます
  • beforeEach(): 指定されたブロック内の各テストの前に実行
  • after(): 指定されたブロック内のすべてのテストの後に実行します
  • afterEach(): 指定されたブロック内の各テストの後に実行されます

これらのフックは、テストに必要なセットアップとティアダウン作業を実行するのに最適な場所です。 一般的な使用例の XNUMX つは、テストを実行する前にデータベースへの接続を確立することです。

"use strict";

const expect = require('chai').expect;
let User = require('../models').User;

describe('Users', function() {

    let database = null;

    before(function(done) {
        
    });

    afterEach(function(done) {
        
    });

    describe('#save()', function() {
        it('should save User data to database', function(done) {
            
        });
    });

    describe('#load()', function() {
        it('should load User data from database', function(done) {
            
        });
    });
});

どれか テストが実行され、関数が私たちに送信されます before() メソッドが実行され (テスト全体で XNUMX 回だけ実行され)、データベースへの接続が確立されます。 これが完了すると、テスト スイートが実行されます。

あるテスト スイートのデータが他のテストに影響を与えたくないので、各スイートを実行した後にデータベースからデータを消去する必要があります。 これは何 afterEach() です。 このフックを使用して、すべてのデータベース データをクリアします。 テスト ケースが実行されるので、次のテストのために白紙の状態から開始できます。

Mocha テストの実行

ほとんどの場合、この部分は非常に単純です。 すでに Mocha をインストールしてプロジェクト ディレクトリに移動していると仮定すると、ほとんどのプロジェクトで必要なのは mocha テストを実行するための引数なしのコマンド:

$ mocha


  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  6 passing (10ms)

テストの場所を Mocha に伝える必要がなかったため、これは前の例とは少し異なります。 この例では、テスト コードは次の予想される場所にあります。 /test.

ただし、テストを実行するときに使用すると便利なオプションがいくつかあります。 たとえば、一部のテストが失敗した場合、変更を加えるたびにスイート全体を実行したくないでしょう。 一部のプロジェクトでは、完全なテスト スイートが完了するまでに数分かかる場合があります。 本当に XNUMX つのテストしか実行する必要がない場合、これは多くの時間を無駄にします。

このような場合は、 実行するテストを Mocha に伝える。 これは、 -g or -f オプション。

個々のテストを実行するには、 -g フラグを付けて、実行するテスト間で共通のパターンを追加します。 たとえば、 #sqrt() テスト:

$ mocha -g sqrt

  Math
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  3 passing (10ms)

ていることに注意してください #abs() テストはこの実行に含まれていませんでした。 それに応じてテスト名を計画する場合、このオプションを利用して、テストの特定のセクションのみを実行できます。

ただし、便利なオプションはこれらだけではありません。 Mocha のその他のいくつかのオプションを以下に示します。

  • --invert:反転 -g & -f マッチ
  • --recursive: サブディレクトリを含める
  • --harmony: ノードのすべてのハーモニー機能を有効にします

Note: オプションの完全なリストは、 mocha -h コマンド、またはオン このページ.

詳細はどこで確認できますか? このトピックについては、短い記事で説明しきれないほどたくさんあります。詳細を知りたい場合は、公式の モカ & チャイ のドキュメントで詳しく説明されています)。

まとめ

Mocha と Chai はどちらも、ライブラリ、コマンドライン ツール、Web サイトなど、あらゆるタイプの Node プロジェクトのテストに使用できることに注意してください。 利用可能なさまざまなオプションとプラグインを利用すると、テストのニーズを非常に簡単に満たすことができるはずです。 これらの各ライブラリは、コードの検証に非常に役立ち、ほぼすべての Node プロジェクトで使用する必要があります。

うまくいけば、これは Mocha と Chai の有用な紹介として役立ちました. ここで説明したこと以外にも学ぶべきことがたくさんあるので、詳細についてはドキュメントを確認してください。

タイムスタンプ:

より多くの スタックアバス