Angular のテスト長い問題を解決する
Angular のプロジェクトに参画して雰囲気で Angular を書き始めましたが、如何せんテストの量が多い。
Angular は ng test
でテストを実行できますが、基本的に全てのテストを実行するので、アプリケーションが大きくなると一度のテストに時間がかかり、気軽にテストできなくてつらい問題が発生します(小さい単位でテストしたい...)
(追記) custom-webpack でテスト対象を動的に変更する
こんな感じでテスト対象を環境変数で指定します。こっちの方が後々楽です。手っ取り早く試したいなら後述の「テストのエントリーポイントを追加する」の方が楽です。
$ TEST_TARGET='./app/<module>' ng test
導入方法
custom-webpack と webpack をインストールします。 custom-webpack は Angular とバージョンを合わせないと動作しないです。
$ npm install -D @angular-builders/custom-webpack
$ npm install -D webpack
環境変数を定義する extra-webpack.config.js
を作成します。
$ cd path/to/<angular-project>
$ touch extra-webpack.config.js
const webpack = require('webpack');
module.exports = (config) => {
config.plugins.push(new webpack.DefinePlugin({ 'process.env.TEST_TARGET': JSON.stringify(process.env.TEST_TARGET || './') }));
return config;
};
既存の angular.json
を修正します。
"test": {
- "builder": "@angular-devkit/build-angular:karma",
+ "builder": "@angular-builders/custom-webpack:karma",
"options": {
+ "customWebpackConfig": {
+ "path": "./extra-webpack.config.js"
+ },
src/test.ts
の require.context()
のパスに環境変数を指定します。
- const context = require.context('./', true, /\.spec\.ts$/);
+ const context = require.context(process.env.TEST_TARGET, true, /\.spec\.ts$/);
以上で完了です。
テストのエントリーポイントを追加する
テストのエントリーポイントを追加して小さい単位、例えば Module 単位などでテストします。
ng test
は(特に何も設定していなければ)テストのエントリーポイントである src/test.ts
の内容を基にテストの対象を決定します。これを書き換えてもテスト対象を絞ることはできますが、毎度書き直すのは面倒です。
...
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
...
--main
オプションを使えば、実行時にエントリーポイントを指定できるので、必要な単位でエントリーポイントを用意します。
以下、 Module 単位でテストする場合の手順です。
test.ts
をコピーする
src/test.ts
を Module のディレクトリにコピーします。
$ cd path/to/<angular-project>
$ cp src/test.ts src/app/<module>
実行
--main
オプションでテストのエントリーポイントを指定して実行します。(私が試した環境の場合 --tsConfig
を指定しないのと ts
のコンパイルに失敗したので同時に指定しています)。
$ cd path/to/<angular-project>
$ ng test --main=src/app/<module> --tsConfig=tsconfig.json
まとめ
--main
オプションを使えば、小さい単位でテストできて嬉しい。でも PR 投げる前には全部テストしよう。