きっかけ
ng testコマンドはアプリケーションをウォッチモードでビルドし、Karmaテストランナーを起動します。
Angular 日本語ドキュメンテーション
とありますが、Dockerコンテナ上のAngularでng test
コマンドを実行するとエラーが発生します。
# テストコマンド実行
ng test
# 以下のエラーが発生
✔ Browser application bundle generation complete.
17 03 2022 05:50:47.581:WARN [karma]: No captured browser, open http://localhost:9876/
17 03 2022 05:50:48.164:INFO [karma-server]: Karma v6.3.17 server started at http://localhost:9876/
17 03 2022 05:50:48.165:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
17 03 2022 05:50:48.212:INFO [launcher]: Starting browser Chrome
17 03 2022 05:50:48.213:ERROR [launcher]: No binary for Chrome browser on your platform.
Please, set "CHROME_BIN" env variable.
目標
Dockerコンテナ上のAngular開発でwathcモードが有効なユニットテストが実行できるようにします。
注意
- 目標に記した通りの挙動になりますが、当方の理解不足のため、理屈を説明できない箇所があります。
- テストコードのコーディングの仕方は解説していません。
当方ユニットテストの仕方を覚えようとng test
実行したところでエラー発生し、その対処を調べ、何とかクリアできたので、もし同様の箇所で詰まっておられる方の助けになればと思い当記事を投稿しました。 - 取り急ぎ当記事の結果をご覧になられたい方は、"まとめ"の節をご覧ください。
環境
- Windows10 Home Version:21H2
- WSL2
- docker desktop Version:4.6.0 (75818)
実践
Dockerコンテナ上に環境構築
ホストPCでPowershellを起動し以下のコマンドを実行します。
# node.jsのDockerイメージを取得する。
docker pull node:14
# カレントディレクトリを取得
$currentdir=$(Covert-Path .)
# コンテナ作成
# ※-vオプションの${currentdir}上のコマンドで取得したカレントディレクトリを使用している。
docker run --name angular-test -p 4200:4200 -v ${currentdir}:/app -w /app -it node:14 /bin/bash
以下はコンテナ内での作業です。
angularプロジェクトを生成します。
# angular/cliをインストールする。
npm install -g @angular/cli
# angularプロジェクトを生成する。
ng new ng-unit-test --directory=./ --routing=false --style=css
# 確認
# ホストPCでブラウザを開きlocalhost:4200にアクセスし画面が表示されることを確認
ng serve --host=0.0.0.0 --poll=2000
※Dokcerコンテナ上のAngularは、単にng serve
コマンドだとホストPCでブラウザでlocalhost:4200にアクセスできません。--host
オプションを指定します。--poll
オプションは変更を検知する時間をミリ秒単位で指定しています。この指定が無いと、Docker上のAngularはng serve
時、コードを変更しても変更を検出しません。
(参考)VM上でng serveするときのメモ - 備忘69
この段階でng test
を実行するとエラーが発生します。
ng test実行時のエラーに対処
-
Dockerコンテナ上にChromiumをインストール
エラーの原因はDockerコンテナ上にブラウザがないことにより発生しているので、Chromiumブラウザをインストールします。apt-get update apt-get upgrade # --no-install-recommendsオプションにより、関連する必須ではないパッケージのインストールを除外する。 apt-get install --no-install-recommends chromium
-
karma.conf.jsを調整する
karma.conf.js// Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html // Chromeの環境変数をセットする。 process.env.CHROME_BIN="/usr/bin/chromium";//←追記 module.exports = function (config) { // ...中略... //↓変更 //browsers: ['Chrome'], browsers: ['ChromeHeadless'], //↑変更 //↓追記 customLaunchers: { ChromeHeadless: { base: 'Chromium', //←Chromiumの接頭は大文字である。 flags: [ '--no-sandbox', '--headless', '--disable-gpu', '--remote-debugging-port=9222' ] } }, //↑追記
-
テスト実行
✔ Browser application bundle generation complete. 18 03 2022 01:50:04.542:WARN [karma]: No captured browser, open http://localhost:9876/ 18 03 2022 01:50:05.185:INFO [karma-server]: Karma v6.3.17 server started at http://localhost:9876/ 18 03 2022 01:50:05.185:INFO [launcher]: Launching browsers ChromeHeadless with concurrency unlimited 18 03 2022 01:50:05.227:INFO [launcher]: Starting browser Chromium 18 03 2022 01:50:19.964:INFO [Chrome Headless 73.0.3683.75 (Linux x86_64)]: Connected on socket G6Hm62Q0vFRxdfamAAAB with id 10245111 Chrome Headless 73.0.3683.75 (Linux x86_64): Executed 3 of 3 SUCCESS (0.408 secs / 0.293 secs) TOTAL: 3 SUCCESS
エラーなくテストが実行できました。
ホストPCでブラウザでlocalhost:9876にアクセスし、ブラウザ上でテスト状況を確認することもできました。
話はそれますが、コンテナ生成時-p
オプションでポート9876を指定していないのにホストPCからlocalhost:9876にアクセスできるのか少し疑問に感じております。話を戻しまして、Angular公式サイトのテストの章に以下のようにあります。
このアクションを確認するためにapp.component.tsに小さな変更を加えて保存してみましょう。 テストが再び実行され、ブラウザが更新されます。そして新しいテストの結果が表示されます。
Angular 日本語ドキュメンテーション小さな変更を加えて保存してみました。
変更が検知されテストが再実行されることを期待したのですが、されませんでした。
karma.conf.jsで以下の設定をしてあるのでウォッチモードが有効のはずです。karma.conf.jsautoWatch: true,
ウォッチモードを働かせる
Angular公式のng testを参照したところ、--pollオプションがあることに気づきました。
--poll
Enable and define the file watching poll time period in milliseconds
(google翻訳)
ファイル監視ポーリング期間を有効にして、ミリ秒単位で定義します。
Angular 日本語ドキュメンテーション
そういえばDokcerコンテナ上のAngularでng serveするとき--pollオプションを指定していた事に気づき、ng test時も同様に指定します。
ng test --poll=2000
コードに変更を加えたところ、期待した通りテストが再実行されました。
まとめ
期待した挙動にするための手順を再掲します。
-
コンテナ上にChromiumをインストールする
apt-get update apt-get upgrade apt-get install --no-install-recommends chromium
-
karma.conf.jsを調整する
karma.conf.js// Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html // Chromeの環境変数をセットする。 process.env.CHROME_BIN="/usr/bin/chromium";//←追記 module.exports = function (config) { // ...中略... //↓変更 //browsers: ['Chrome'], browsers: ['ChromeHeadless'], //↑変更 //↓追記 customLaunchers: { ChromeHeadless: { base: 'Chromium', //←Chromiumの接頭は大文字である。 flags: [ '--no-sandbox', '--headless', '--disable-gpu', '--remote-debugging-port=9222' ] } }, //↑追記
-
--poll
オプションを指定してng test
を実行ng test --poll=2000
以上です。
参考にさせていただいたサイト、記事
- VM上でng serveするときのメモ - 備忘69
- AngularのテストをDocker(CentOS 7)上で回すときに設定したこと - Qiita
- GitHub - geoffroyvergne/docker-angular-test-suite: Docker image to test (unit and e2e) angular appliaction
ありがとうございました。