[Jest] テストのタイムアウト時間を変更する

2021.12.19

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、テストフレームワークJestのテストのタイムアウト時間を変更してみました。

test()の既定のタイムアウト時間は5秒

外部のAPIなどを叩くなどの重い処理を実行するテストで、実行時間が長くなってしまう時があります。

例えば次のような実行に5秒以上の時間を要するテストがあります。

test('テスト', async (): Promise<void> => {
  await new Promise((r) => setTimeout(r, 6000)); //6秒待機

  expect(1 + 1).toBe(2);
});

Jestで実行してみます。するとAsync callback was not invoked within the 5000 ms timeout specified by jest.というエラーとなりました。

$  npx jest
 FAIL  test/sampleHandler.test.ts (8.332 s)
  ✕ テスト (5001 ms)

  ● テスト

    : Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:

    > 1 | test('テスト', async (): Promise<void> => {
        | ^
      2 |   await new Promise((r) => setTimeout(r, 6000));
      3 |
      4 |   expect(1 + 1).toBe(2);

      at new Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
      at Object.<anonymous> (test/sampleHandler.test.ts:1:1)

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

これはJestのtest()の既定のタイムアウト時間が5秒であるためです。

Note: The default timeout is 5 seconds.

タイムアウト時間を変更する

そこでテストのタイムアウト時間を変更してみます。方法は2つあります。

方法1. test()の第3引数を指定する

ここまで使ってきたtest()ですが、実は第3引数を指定することにより、タイムアウト時間を設定することができます。

test(name, fn, timeout)

待機時間を8秒(8000ms)に設定してみます。

test('テスト', async (): Promise<void> => {
  await new Promise((r) => setTimeout(r, 6000));

  expect(1 + 1).toBe(2);
}, 8000);

テストを実行します。すると実行に6005msを要していますが、タイムアウトとならずテストが実行できました。

$  npx jest
 PASS  test/sampleHandler.test.ts (9.238 s)
  ✓ テスト (6005 ms)

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

方法2. setTimeout()を使う

タイマーモックのsetTimeout()を使用しても待機時間を設定できます。

これを使用することにより、複数のテストのタイムアウトを一括で設定できます。

jest.setTimeout(8000);

test('テスト', async (): Promise<void> => {
  await new Promise((r) => setTimeout(r, 6000));

  expect(1 + 1).toBe(2);
});

test('テスト', async (): Promise<void> => {
  await new Promise((r) => setTimeout(r, 6000));

  expect(1 + 1).toBe(2);
});

テストを実行すると、実行にそれぞれ6007ms、6005msを要していますが、それぞれタイムアウトとならずテストが実行できました。

$  npx jest
 PASS  test/sampleHandler.test.ts (14.653 s)
  ✓ テスト (6007 ms)
  ✓ テスト (6005 ms)

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

まとめ

  • Jestの既定のタイムアウト時間は5秒
  • 個別のテストのタイムアウト時間の変更はtest()の第3引数を指定する
  • 複数のテストのタイムアウト時間の変更はsetTimeout()を使用する

以上