JestでExpressのAPIテスト環境を構築してみた


概要

今回は、Jestを利用してExpressで作成したAPIのテスト環境を構築したので、概要だけご紹介です。詳しい環境構築の方法等は、公式サイトのリンクを適宜記載してますので、御覧ください。

環境

  • Node.js : v8.11.3
  • npm : 6.5.0
  • sequelize : 4.37.10
  • sqlite3 : 4.0.6
  • Jest : 23.6.0
  • jest-jenkins-reporter : 1.0.2
  • supertest : 3.4.2

利用しているnpmパッケージのご紹介

1. Sequelize

Node.js用のORMです。今回は、Sequelizeを使って、DBのマイグレーションから操作まで行いました。 PostgreSQL、MySQL、SQLiteに対応してます。今回は、本番系でMySQLを利用し、テスト用DBにSQLiteを利用しました。

Sequelizeの公式サイト

2 sqlite3

OSSのRDBMSで、サーバではなくファイルベースで動作します。MySQLとの完全互換はありませんが、本システムのテストには十分なため、テスト用DBとして利用しました。

SQLiteの公式サイト

3. Jest

Jestは、Facebook社がOSSとして開発を進めている、JavaScriptのユニットテストのためのツールです。今回はこのフレームワークを利用して、テストを作成しました。

Jestの公式サイト

4. jest-jenkins-reporter

Jestのテスト結果をJenkinsで集計するためのプラグインです。
jest-jenkins-reporterの公式サイト

5. Supertest

HTTPリクエストとレスポンスのアサーションを簡単に実装できるパッケージです。Jestと組み合わせて、テストを実装します。

Supertestの公式テスト

テスト実行環境の構成

以下、簡単なテスト実行環境の構成になります。

簡単な説明

①テスト用DBの作成、②テスト用データ挿入

Sequelizeには、ORマッパーとしての機能だけでなく、DBのマイグレーション機能があります。この機能を利用して、SQLiteでテスト用DBを作成します。また、以下のように、config/config.jsonによって、環境別でDBを切り替えることも可能です。

マイグレーションについて

config/config.json
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

⑦レスポンスをテスト

JestとSupertestによるテストの書き方ですが、以下の記事が参考になりそうです。

Facebook製のJavaScriptテストツール「Jest」の逆引き使用例

私は以下のようなフォルダ構成にしています。

root
│
├─__test__ # テストファイル格納フォルダ
│  |─hogehogeApi.spec.js # テストファイル
│  |─fugafugaApi.spec.js
│  |─...
│
│   

テストコードの一部も載せておきます。

const request = require('supertest');
const server = require('../bin/www');

// テストが終了したら、サーバをクローズする
afterAll(() => {
    'use strict';

    server.close();
});

describe('hogehoge API のテスト', () => {
    'use strict';

    describe('正常系テスト', () => {

        test('レスポンスが適切な値を持っていることを確認', async () => { 

            const response = await request(server).get('/api/hogehoge');

            expect(response.body[0].hogeName).toBe('hogehoge');
            expect(response.body[0].seq).toBe(1);

        });

        test('ステータスコードが200であることを確認', async () => { 

            const response = await request(server).get('/api/hogehoge');
            expect(response.statusCode).toBe(200);

        });
    });
});

テストの実行には、以下のコマンドをnpm scriptsに登録して実行しています。--coverageオプションを使うと、カバレッジも一緒に出力してくれます。

jest --coverage --verbose

結果は以下のように出力されます。

PASS __test__/hogehogeApi.spec.js
   hogehoge API のテスト
     正常テスト
         ✓ レスポンスが適切な値を持っていることを確認 (131ms)
         ✓ ステータスコードが200であることを確認 (20ms)

・
・
・
-------------------------------|----------|----------|----------|----------|-------------------|
 File                           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
 -------------------------------|----------|----------|----------|----------|-------------------|
 All files                      |     51.6 |    28.32 |    63.72 |    56.06 |                   |
  hogehog                       |      100 |      100 |      100 |      100 |                   |
   express.js                   |      100 |      100 |      100 |      100 |                   |
  hogehoge/bin                  |    56.67 |    33.33 |    66.67 |    56.67 |                   |
   www                          |    56.67 |    33.33 |    66.67 |    56.67 |... 71,73,74,75,77 |

⑧jest-Jenkins-reporterでテスト結果出力

package.jsonに、テストの集計結果の出力フォルダなどを設定してます。この出力ファイルをJenkinsで読み込みます。

package.json
"jest": {
    "testResultsProcessor": "jest-jenkins-reporter"
  },
"jestSonar": {
    "reportPath": "reports",
    "reportFile": "report.xml",
    "indent": 4
}

Jestを使ってみて

  • 今まで、テストをするのに複数のパッケージを組み合わせていたが、Jestだけでテストするための主要な機能が揃うのでとても便利。
  • ReactのようなViewのテストも実行できるようなので、今後試してみたい。