5分で始めるJestで快適テスト生活


Jestとは

JavaScriptのためのテスティングフレームワークです。
一般的にプログラミング言語のテストというと

  • テストランナー
  • アサーションライブラリ
  • テストモック・テストダブル用ライブラリ

などいくつかのライブラリ群が必要になりますが、これらを全て自分で集めるのはなかなかに大変な作業です。

そこでJestでは最初からテストに必要なものを一式揃えることでテストのためのフレームワークを提供する仕組みになっています。

導入

さっそく導入します。

yarn add --dev jest

今後何度も実行することになるのでpackage.jsonにショートハンドを追加しておきます。

package.json
{
+ "scripts": {
+   "test": "jest"
+ },
  "devDependencies": {
    "jest": "^25.1.0"
  }
}

まずはお試し

簡単なfunctionを用意してテストしてみましょう。
まずはテスト対象の関数とテストそのものを作ります。

getBigger.js
module.exports = function(a, b) {
    if(a > b) 
    {
        return a
    }
    else
    {
        return b
    }
}
getBigger.test.js
const sum = require('./getBigger');

test('get bigger one 1 or 2', () => {
  expect(sum(1, 2)).toBe(2);
});

この時点でファイル構成は以下の通りになっているはず。

.
├── package.json
├── getBigger.js
└── getBigger.test.js

先ほどpackage.jsonにコマンドを書いてあるので実行します.

npm test

こんな結果になれば成功!

> @ test /Development/jest-sample
> jest

 PASS  ./getBigger.test.js
  ✓ get bigger one 1 or 2 (3ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.349s
Ran all test suites.

Let's TDD

無事テストが実行できたのでこれからはテストし放題です。
簡易TDDとして小さい方を返す関数も作ってみましょう。

まずはテストを作ります。
関数名は先ほどのgetBiggerに合わせてgetSmallerとします。

getSmaller.test.js
const sum = require('./getSmaller');

test('get smaller one 1 or 2', () => {
  expect(sum(1, 2)).toBe(1);
});

当然ですがテスト結果は失敗です。

$ npm test getSmaller

> @ test /Development/jest-sample
> jest "getSmaller"

 FAIL  ./getSmaller.test.js
  ● Test suite failed to run

    Cannot find module './getSmaller' from 'getSmaller.test.js'

    However, Jest was able to find:
        './getSmaller.test.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

    > 1 | const sum = require('./getSmaller');
        | ^
      2 | 
      3 | test('get smaller one 1 or 2', () => {
      4 |   expect(sum(1, 2)).toBe(1);

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:276:11)
      at Object.<anonymous> (getSmaller.test.js:1:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.981s
Ran all test suites matching /getSmaller/i.
npm ERR! Test failed.  See above for more details.

そんな関数ねーよと言われてるので関数のスケルトンを作ります。

getSmaller.js
module.exports = function(a, b) {
}
$npm test getSmaller

> @ test /Development/jest-sample
> jest "getSmaller"

 FAIL  ./getSmaller.test.js
  ✕ get smaller one 1 or 2 (5ms)

  ● get smaller one 1 or 2

    expect(received).toBe(expected) // Object.is equality

    Expected: 1
    Received: undefined

      2 | 
      3 | test('get smaller one 1 or 2', () => {
    > 4 |   expect(sum(1, 2)).toBe(1);
        |                     ^
      5 | });

      at Object.<anonymous>.test (getSmaller.test.js:4:21)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.297s
Ran all test suites matching /getSmaller/i.
npm ERR! Test failed.  See above for more details. 

関数は見つかりましたがテスト実行結果がNG、想定通りです。
中身を実装してテストしてみましょう。

module.exports = function(a, b) {
    if(a < b) 
    {
        return a
    }
    else
    {
        return b
    }
}
$ npm test getSmaller

> @ test /Development/jest-sample
> jest "getSmaller"

 PASS  ./getSmaller.test.js
  ✓ get smaller one 1 or 2 (4ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.823s
Ran all test suites matching /getSmaller/i.

無事にテストがパスしました!
お疲れ様でした.