いつも ng new 一発でテスト環境まで準備済みだが、ふとユニットテスト環境を作るのにどういうパッケージとどういう設定が必要かきになったので試してみた記録
テスト環境がない状態で Angular アプリケーションを用意
ng new
のオプションにめちゃくちゃ都合のいいminimal
があったのでこれを使ってアプリケーションを用意
$ npx @angular/cli new ng-sample --minimal ? Would you like to add Angular routing? No ? Which stylesheet format would you like to use? SCSS [ https://sass-lang.com/documentation/syntax#scss ] CREATE ng-sample/README.md (1038 bytes) CREATE ng-sample/.gitignore (631 bytes) CREATE ng-sample/angular.json (3215 bytes) CREATE ng-sample/package.json (880 bytes) CREATE ng-sample/tsconfig.json (489 bytes) CREATE ng-sample/browserslist (429 bytes) CREATE ng-sample/tsconfig.app.json (210 bytes) CREATE ng-sample/src/favicon.ico (948 bytes) CREATE ng-sample/src/index.html (307 bytes) CREATE ng-sample/src/main.ts (372 bytes) CREATE ng-sample/src/polyfills.ts (2835 bytes) CREATE ng-sample/src/styles.scss (80 bytes) CREATE ng-sample/src/assets/.gitkeep (0 bytes) CREATE ng-sample/src/environments/environment.prod.ts (51 bytes) CREATE ng-sample/src/environments/environment.ts (662 bytes) CREATE ng-sample/src/app/app.module.ts (314 bytes) CREATE ng-sample/src/app/app.component.ts (1470 bytes)
テストに必要なパッケージのインストール
- 通常 Angular アプリケーションのユニットテストには Jasmine と Karma が使われているので同じ環境を揃えにいく
- Karma の Installation を参考にしてみると最低限必要なパッケージがわかる
$ yarn add jasmine-core karma karma-jasmine karma-chrome-launcher -D
- テストの実行すると起動することがわかる
$ yarn karma start yarn run v1.21.1 $ /Users/path/to/ng-sample/node_modules/.bin/karma start 12 06 2020 09:34:34.912:WARN [karma]: No captured browser, open http://localhost:9876/ 12 06 2020 09:34:34.978:INFO [karma-server]: Karma v5.1.0 server started at http://0.0.0.0:9876/
設定ファイルを書く
- Karm の init コマンドで conf ファイルを作る(すべて default で作成)
yarn karma init yarn run v1.21.1 $ /Users/path/to/ng-sample/node_modules/.bin/karma init Which testing framework do you want to use ? Press tab to list possible options. Enter to move to the next question. > jasmine Do you want to use Require.js ? This will add Require.js plugin. Press tab to list possible options. Enter to move to the next question. > no Do you want to capture any browsers automatically ? Press tab to list possible options. Enter empty string to move to the next question. > Chrome > What is the location of your source and test files ? You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js". Enter empty string to move to the next question. > Should any of the files included by the previous patterns be excluded ? You can use glob patterns, eg. "**/*.swp". Enter empty string to move to the next question. > Do you want Karma to watch all the files and run the tests on change ? Press tab to list possible options. > yes Config file generated at "/Users/path/to/ng-sample/karma.conf.js". ✨ Done in 33.58s.
- 作成された karma.conf.js は以下のようになっている
// Karma configuration // Generated on Wed Jun 10 2020 22:37:18 GMT+0900 (GMT+09:00) module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser files: [ ], // list of files / patterns to exclude exclude: [ ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: true, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['Chrome'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity }) }
- ここでもう一度 start をすると Chrome が立ち上がりテストが実行される
Angular CLI 経由でテストを動かす
- angular.json に test architect を追加する
- builder には
@angular-devkit/build-angular:karma
を指定 - options は angular_devkit/build_angular/src/karma/schema.json を見ながら省略できないパラメータを指定
- 必須項目は angular_devkit/build_angular/src/karma/schema.json の required を見ると確認できる
- 現時点では main, tsConfig, karmaConfig の 3 つ
- builder には
diff --git a/angular.json b/angular.json index 05240c6..d5132e9 100644 --- a/angular.json +++ b/angular.json @@ -93,6 +93,14 @@ } } }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "tsConfig": "", + "karmaConfig": "karma.conf.js" + } + }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": {
- tsConfig は最低限 key だけあれば良い
- karmaConfig にはすでに作成済みの karma.conf.js を指定
- main(entry-point) として指定する src/test.ts を準備
- 参考になる資料が見つからなかったので minimal でなければ生成されるファイルを用意
// This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { keys(): string[]; <T>(id: string): T; }; }; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. context.keys().map(context);
- angular-devkit/build-angular を使用することを karma.conf.js に明記
diff --git a/karma.conf.js b/karma.conf.js index 27a1565..238b42e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -8,7 +8,12 @@ module.exports = function (config) { // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('@angular-devkit/build-angular/plugins/karma'), + ], // list of files / patterns to load in the browser files: [],
- Angular アプリケーションのテストの実行に Zone が必要なので polyfill を読み込む
diff --git a/angular.json b/angular.json index 6f4687e..e39fec0 100644 --- a/angular.json +++ b/angular.json @@ -98,7 +98,8 @@ "options": { "main": "src/test.ts", "tsConfig": "", - "karmaConfig": "karma.conf.js" + "karmaConfig": "karma.conf.js", + "polyfills": "src/polyfills.ts" } }, "extract-i18n": {
- Jasmine 用の型定義が必要なので
@types/jasmine
をインストール
$ yarn add @types/jasmine -D
サンプルテストコードをおいて実行してみる
- app.component.spec.ts を用意
import { TestBed, async } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [AppComponent], }).compileComponents(); })); it('should create the app', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; expect(app).toBeTruthy(); }); });
- テストの実行
$ yarn test --watch false yarn run v1.21.1 $ ng test --watch false 10% building 1/1 modules 0 active12 06 2020 13:00:14.871:INFO [karma-server]: Karma v5.1.0 server started at http://0.0.0.0:9876/ 12 06 2020 13:00:14.873:INFO [launcher]: Launching browsers Chrome with concurrency unlimited 12 06 2020 13:00:14.878:INFO [launcher]: Starting browser Chrome 12 06 2020 13:00:27.166:INFO [Chrome 83.0.4103.97 (Mac OS 10.15.5)]: Connected on socket lsZPFDaFH_rTC8F2AAAA with id 33650755 Chrome 83.0.4103.97 (Mac OS 10.15.5): Executed 1 of 1 SUCCESS (0.248 secs / 0.171 secs) TOTAL: 1 SUCCESS ✨ Done in 33.15s.
テストが動いた👏
テスト用のパッケージを確認
- minimal 指定しない場合にインストールされるテスト用のパッケージを確認
上でインストール済みのパッケージ
jasmine-core
- https://www.npmjs.com/package/jasmine-core
- JavaScript Testing Framework の Jasmine を使うための core パッケージ
karma
- https://www.npmjs.com/package/karma
- 実際のブラウザを起動してテストを実行するテストランナー
karma-jasmine
- https://www.npmjs.com/package/karma-jasmine
- Jasmine 用のアダプターパッケージ
karma-chrome-launcher
- https://www.npmjs.com/package/karma-chrome-launcher
- Karma が Google Chrome, Google Chrome Canary, Google Chromium を起動するのに必要なパッケージ
上でインストールしていないパッケージ
jasmine-spec-reporter
- https://www.npmjs.com/package/jasmine-spec-reporter
- テストの実行結果がリアルタイムにコンソールに表示するためのパッケージ
karma-jasmine-html-reporter
- https://www.npmjs.com/package/karma-jasmine-html-reporter
- HTML 上に実行結果を表示するためのパッケージ
karma-coverage-istanbul-reporter
- https://www.npmjs.com/package/karma-coverage-istanbul-reporter
- code coverage をレポートするためのパッケージ
protractor
- https://www.npmjs.com/package/protractor
- E2E 用のパッケージ
感想
test.ts の役割がモヤッとしている…が、基本的には Karma の設定をするだけで構築できることがわかった。インストールされているパッケージの役割もわかったのがよい。