とんかつ時々あんどーなつ

〜たとえ低空でも飛行していられるように〜

Angular アプリケーションの単体テストのフレームワークを Jest に変更するまで

はじめに

今回は Angular アプリケーションの単体テストフレームワークを Jasmine / Karma から Jest に変更する方法を調べてみた。 Jest にする理由は「早いらしい」「ナウい」とかそんな感じだが、使ってみたいので試してみる。

Angular アプリケーションで使うには

まずは置き換えるためのライブラリを探す。$ ng add で気軽にライブラリの追加ができると嬉しい。 以前 E2E テストのライブラリを置き換えたときに使った Briebug Software · GitHub のライブラリが便利だったことを思い出す。

kasaharu.hatenablog.com

Jest 用のライブラリもここから探すことに。

github.com

ありました。今回はこれを使って置き換える。

Jest Angular Schematic

導入

$ ng add コマンドでインストールをするだけ、簡単である。

$ yarn ng add @briebug/jest-schematic

変更内容は以下のような感じ。

DELETE karma.conf.js
DELETE src/test.ts
CREATE jest.config.js (180 bytes)
CREATE setup-jest.ts (860 bytes)
CREATE test-config.helper.ts (611 bytes)
UPDATE package.json (1153 bytes)
UPDATE angular.json (3709 bytes)
UPDATE tsconfig.spec.json (316 bytes)

Karma の設定ファイルを消して Jest の設定を追加しているのがわかる。よい。

実行

$ yarn test で実行すると既存のテストが Jest で動く!

yarn test
yarn run v1.22.10
$ ng test
 PASS  src/app/app.component.spec.ts
  AppComponent
    ✓ should create the app (210 ms)
    ✓ should have as title 'ng-sample' (164 ms)
    ✓ should render title (105 ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        2.396 s
Ran all test suites.
✨  Done in 4.85s.

注意点

1. code coverage を表示するためのオプションが Karma と異なる

Karma では --code-coverage を指定していたが Jest では --coverage を指定する必要がある。npm script や CI なのでオプションを指定している場合は変更が必要になる。

2. code coverage の report 出力場所が Karma と異なる デフォルトでは <app-root>/coverage/<app-name>/index.html に出力されるが Jest では <app-root>/coverage/lcov-report/index.html に出力される。こちらも CI で artifact としてアップロードなどしていたら変更が必要になる。

3. karma-coverage パッケージが残ったまま Angular v11 で karma-coverage-istanbul-reporter の代わりに入った karma-coverage が残ったままになるので、インストールされている場合は自分で削除する必要がある。

Jasmine / Karma と比較

とりあえず、実行時間を比較してみるが Karma 16s に対して Jest 6s だった。早い。

Jasmine / Karma

yarn ng test --watch false --code-coverage
yarn run v1.22.10
$ ng test --watch false --code-coverage
There is a known issue with Karma and karma-coverage. Tests that exceed the coverage threshold will not fail. This will be fixed in Karma 5.2.x soon.
⠙ Generating browser application bundles (phase: building)...20 01 2021 20:04:25.266:INFO [karma-server]: Karma v5.1.1 server started at http://localhost:9876/
20 01 2021 20:04:25.268:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
20 01 2021 20:04:25.273:INFO [launcher]: Starting browser Chrome
✔ Browser application bundle generation complete.
20 01 2021 20:04:30.996:INFO [Chrome 87.0.4280.141 (Mac OS 10.15.7)]: Connected on socket n6D88S5IGRku_P0mAAAA with id 39410406
Chrome 87.0.4280.141 (Mac OS 10.15.7): Executed 3 of 3 SUCCESS (0.197 secs / 0.184 secs)
TOTAL: 3 SUCCESS

=============================== Coverage summary ===============================
Statements   : 100% ( 6/6 )
Branches     : 100% ( 0/0 )
Functions    : 100% ( 0/0 )
Lines        : 100% ( 5/5 )
================================================================================
✨  Done in 16.07s.

Jest

yarn test --watch false --coverage
yarn run v1.22.10
$ ng test --watch false --coverage
 PASS  src/app/app.component.spec.ts
  AppComponent
    ✓ should create the app (252 ms)
    ✓ should have as title 'ng-sample' (160 ms)
    ✓ should render title (119 ms)

--------------------|---------|----------|---------|---------|-------------------
File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------|---------|----------|---------|---------|-------------------
All files           |     100 |      100 |     100 |     100 |
 app.component.html |     100 |      100 |     100 |     100 |
 app.component.ts   |     100 |      100 |     100 |     100 |
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        2.871 s, estimated 3 s
Ran all test suites.
✨  Done in 6.15s.

まとめ

普段 Jasmine / Karma でテストを書くことが多いが、思い切って Jest に移行したいので試してみた。 移行自体はすごい簡単だったので、しばらく使ってみた。 既存のスタックだと、テストケースが多くなったときにテストに時間かかるのが課題だったので解決することを期待する。