TestCafe（１）コマンドと設定

## 記事の概要
　TestCafeについて記述します。
　インストールや「GettingStart」に関わる記事はそこそこあるようですので、私はコマンドラインや設定、APIの細かなことを覚書として書いておこうと思っています。
　基本的な事を以下の2回に分けて書こうと思っていますが、場合によってはもう少しかかるかもしれません。
（１）コマンドラインと設定ファイルについて
（２）テストファイルの概要といくつかの問題点
　基本的な事と私の関心のあることしか書きませんので、興味のある部分は原文を読んでください。

## 経緯
　ASP.Net Core + Vue.jsのコンポーネントを作ろうとしていたのですが、コンポーネントなら単体テストもしっかりしないといけないと考えると、思いのほか細かいWeb画面でのテストが多くなってきたのでテスターを利用しようと考えました。
　そこで最初に考えたのが以前少し使ってみたことのある「selenium2」だったのですが、いまいち使い勝手が悪かった記憶があり、ほかに何かないかと調べてみると、タイトルにある「TestCafe」に行き当たりました。「selenium2」で面倒だったドライバの管理（ちょくちょく変わるので面倒）が無いことや、ページの読み込みやエレメントの参照などの非同期処理をうまく行う為のタイムアウト処理が基本で組み込まれていることなどからこちらを使うことにしました。ほかのツールはseleniumにかぶせて使うので、なんか2つも組み込むのも嫌で...。
　簡単に使うなら「TestCafe studio」を使うのがいいのかもしれませんが、貧乏なのでコマンドラインかな...。資料は英語なので簡単に見れるように調べたこと、気づいたことを書いておきます。

## コマンドライン
　コマンドラインは以下の通りです。（パスは通しておいてください。）

　testcafe [options] <カンマ「,」区切りのブラウザリスト> <テストアフィル>

### （１）ブラウザリストについて
　ブラウザリストは以下の様な指定方法があります。

| 指定方法 |対象ブラウザ | 説明 |
|:----------------- |:----------------- |:----------------- |
| エリアス | 共通 | 内部で設定されている。コマンドラインオプション「-b」で利用可能なブラウザのエリアスリストが表示される |
| パスの指定 | 共通 | 「path:」以降にパスを指定できる。ポータブルブラウザも利用可能。Windowsでは「path:」も含めてこのオプション全体をダブルクォートで囲むとよい |
| 全指定 | 共通 | 「all」を指定するとインストールされている全てのブラウザでテストする |
| ブラウザのヘッダ部分無し | Chrome,Firefox | ブラウザの指定に「firefox:headless」のように「:headless」を追加する |
| （スマホ等の）デバイスエミュレーション | Chrome | 「chrome:emulation:device=iphone X」のようにデバイスを記述する |
| リモートブラウザの利用 | 共通 | 「remote」と記述すると接続するURLが表示されます。その接続先にネットワーク内の端末でブラウザを立ち上げて接続すると、そのブラウザ上でテストが実行できます。「remote:3」と記述すると3つのブラウザでテストできる様です。 |
| ブラウザのプラグイン利用 | 共通 | リモートで接続する際に特定のプラグインを利用する場合に利用 |
| ブラウザのオプション | 共通 | Windowsの場合ダブルクォートで囲んでオプションをそのまま設定できる（例："chrome --start-fullscreen"） |

　基本的には「chrome」や「ie」等のエリアスを利用するのですが、設定されているアリアスは以下の通りです。

| エリアス | 対象ブラウザ |
|:----------------- |:----------------- |
| chromium | Chromium |
| chrome|Google Chrome: Stable, Beta, Dev and Canary|
| chrome-canary | Google Chrome: Canary |
| ie | Internet Explorer (11+) |
| edge | Microsoft Edge |
| firefox | Mozilla Firefox |
| opera | Opera |
| safari | Safari |

　端末にインストールされているブラウザのエリアスが以下のオプションでコマンドを実行すると表示されます。この例では3つのブラウザがインストールされています。

```
c:\tmp>testcafe -b
firefox
chrome
ie
```

　**all：インストールされているブラウザ全て**
　「all」を指定すると、先にコマンドラインで利用可能なブラウザを全てテストしてくれます。ブラウザによって処理を分けたい場合はテストファイルにうまく記述すれば別のテストが可能です。ブラウザによる分岐はテストファイルの時に説明します。

　**remote：別の端末から任意のブラウザをテストできる**
　「remote」を記述すると、その端末はテストサーバーとなり、接続するためのURLが表示されます。ネットワークが繋がっている端末（実施している端末自身でもOK)にこのURLで接続するとテストが実行されます。なんと便利！　スマホなんかのテストができます。スマホで利用するために後述のオプション「--qr-code」を利用するとQRコードまで出してくれます。

### (2)コマンドラインオプションと定義ファイル
　実行時のコマンドラインオプションを説明しますが、ほとんど同じことが定義ファイルでも定義できます。また、実行時のタイムアウト設定など、テスト内で動的に変更することも可能です。同じ設定がされた場合、基本的に「定義ファイル」＜「コマンドライン」＜「テスト実行時の動的設定」となるようです。
　コマンドラインや設定ファイルで定義できるものは以下のものがあるようです。

| 機能 | コマンドライン | 設定ファイル | 概要 |
|:----------------- |:----------------- |:----------------- |:----------------- |
| コマンドラインヘルプ | -h, --help | 無し | ヘルプを表示する |
| バージョン確認 | -v, --version | 無し | バージョンを表示する  |
| ブラウザリストの取得 | -b, --list-browsers | 無し | 利用可能なブラウザのエリアスリストを表示する |
| ブラウザの指定 | 無し（オプションじゃない） | browsers | ブラウザを指定する |
| テストファイルの指定 | 無し（オプションじゃない） | src | テストファイルを指定する |
| レポートの設定 | -r <name[:output],[...]>, --reporter <name[:output],[...]|reporter | "内部で指定されているレポートの形式（xunit,json,spe等）やカスタムレポーターのプラグインを指定。<br />「:」で区切って出力ファイルを指定できる" |
| スクリーンショット | -s, --screenshots <option=value[,option2=value2,...]> | screenshots | テスト時のブラウザのスクリーンショットを撮る。以下のオプションを設定。<br />　path：出力するフォルダを設定<br />　takeOnFails：テスト失敗時にスクリーンショットを撮る（例：-s takeOnFails=true）<br />　pathPattern：スクリーンショットの出力パスのパターンを定義する。（パターンのプレースフォルダーは補足に記述）<br />　fullPage：スクリーンショットの為に全画面表示にする|
|スクリーンショットを禁止する | --disable-screenshots | disableScreenshots | スクリーンショットを禁止する。|
| ビデオ | --video <basePath> | videoPath | テストを録画する。（例：--video reports/screen-captures）|
| ビデオのオプション | --video-options <option=value[,option2=value2,...]> | videoOptions | テストの録画ぷションを設定する。オプションは以下の通り。<br />　failedOnly：(true/false)エラーのテストのみ録画する。(default：false)<br />　singleFile：(true/false)単一ファイルでろくがする。Falseならばテストごとのファイルで録画する(default：false)<br />　ffmpegPath：ffmpegエンコーダーのパスを指定する。（(default：auto-detect）<br />　pathPattern：ビデオファイルの出力パスのパターンを定義する。【パターンのプレースフォルダーは補足に記述） |
| ビデオオンコードのオプション | --video-encoding-options <option=value[,option2=value2,...]> | videoEncodingOptions | ffmpegのオプションを指定する（詳細はffmpegを調べる）|
| 隔離(quarantine)モード | -q, --quarantine-mode | quarantineMode | 隔離モードを設定する|
| デバッグモード | -d, --debug-mode | debugMode | デバッグモードを設定する。設定すると最初の動作で一時停止する。フッターにコントロール用のエリアが表示される|
| エラー発生時にデバッグモードに | --debug-on-fail | debugOnFail | エラー発生時に自動的にデバッグモードに移行 |
| JavaScriptエラーを無視する | -e, --skip-js-errors | skipJsErrors | デバッグ時にWebページ上のJavaScriptエラーを無視する。設定しない場合、JavaScriptエラーが発生すると処理を中止し、エラーメッセージとスタックトレースをレポートに出力する。 |
| 補足しないエラーを無視する | -u, --skip-uncaught-errors | skipUncaughtErrors | デバッグ時にWebページ上の補足していないエラーを無視する。設定しない場合、補足していないエラーが発生すると処理を中止し、エラーメッセージとスタックトレースをレポートに出力する。 |
| テストを限定する | -t <name>, --test <name> | filter | テストファイルの特定のテストのみ実行する。 |
| | -T <pattern>, --test-grep <pattern> | filter.testGrep | テストファイルの特定のテストをワイルドカード「*」を利用した条件で合致したものみ実行する。|
| fixtureを限定する | -f <name>, --fixture <name> | filter.fixture | テストファイルの特定のfixtureのみ実行する。 |
| | -F <pattern>, --fixture-grep <pattern> | filter.fixtureGrep | テストファイルの特定のfixtureをワイルドカード「*」を利用した条件で合致したものみ実行する。 |
| テストのメタデータを限定する | --test-meta |<key=value[,key2=value2,...]> | filter.testMeta | fixtureに設定されたメタデータが合致するテストのみ実行する |
| fixtureのメタデータを限定する | --fixture-meta <key=value[,key2=value2,...]> | filter.fixtureMeta | fixtureに設定されたメタデータでワイルドカード「*」を利用した条件で合致したものみ実行する。 |
| テスト実行直前に実行するコマンド | -a <command>, --app <command>|appCommand|テスト実行前に実行するコマンドを設定。テスト実行前に実行される
事項前待機時間|--app-init-delay <ms>|appInitDelay|テスト実行の待機時間（デフォルト：1000ms）
同時実行制御|-c <n>, --concurrency <n>|concurrency|同時実行するテスト対象の個数を設定する
セレクタのタイムアウト|--selector-timeout <ms>|selectorTimeout|テストで利用するセレクタのタイムアウト時間（デフォルト：10000ms）
アサーションのタイムアウト|--assertion-timeout <ms>|assertionTimeout|テストで利用するアサーションのタイムアウト時間（デフォルト：3000ms）
ページロード処理のタイムアウト|--page-load-timeout <ms>|pageLoadTimeout|ページロード時のタイムアウト時間（デフォルト：3000ms）
テスト実行速度|--speed <factor>|speed|テストの実行速度。最速「1」、最遅「0.01」（デフォルト：1）
外部JavaScriptファイルの利用|--cs <path[,path2,...]>, --client-scripts <path[,path2,...]>|clientScripts|テスト時に各ページに対して指定したJavaScriptファイルを取り込ませる。モックの処理などを記述できる
テスト実行に利用するポート番号|--ports <port1,port2>|port1, port2|テストで利用するポート番号で[0-65535]の範囲で指定する。未指定の場合は自動的に設定される
ホスト名の指定|--hostname <name>|hostname|ホスト名を指定する。リモート実行の場合などに利用
プロキシの設定|--proxy <host>|proxy|プロキシを指定します。
プロキシを無視する設定|--proxy-bypass <rules>|proxyBypass|指定したURLでプロキシを利用しないように設定します。
SSLの設定|--ssl <options>|ssl|ブラウザとTestCafe間の接続でsslを利用するように設定。オプションはNode.jsのHTTPサーバーのオプションが設定可能
ライブモード|-L, --live|×|このモードで実施するとテスト関連のファイルが変更されるとテストが実行される
デバッグモード|--dev |developmentMode|ログや診断メッセージが出力されます。サポートに連絡する場合にこのモードで実行したレポートを利用してください。
リモートのQRコード|--qr-code|qrCode|リモートの場合に接続用のURLのQRコードを表示します。
エラー即時停止|--sf, --stop-on-first-fail |stopOnFirstFail|佐為氏のエラーでテストが終了します。全てのエラーリポートが不要ですぐに修正したい時に利用してください。
設定ファイルのパス|--ts-config-path <path>|tsConfigPath|TypeScriptの設定ファイルのパスを設定します。
キャッシングの禁止|--disable-page-caching|disablePageCaching|ブラウザのキャッシングを禁止する
コマンドラインでの色利用を有効にする|--color|color|コマンドラインでの色利用を有効にする（デフォルト）
コマンドラインでの色利用を無効にする|--no-color|noColor|コマンドラインでの色利用を無効にする

　スクリーンショットやビデが取れるようで、今度試してみようと思います。
　ファイル名の指定に使えるプレースフォルダには以下のものがあります。

| プレースフォルダ | 出力内容 |
|:----------------- |:----------------- |
| ${DATE} | 日付 (YYYY-MM-DD) |
| ${TIME} | 時刻 (HH-mm-ss) |
| ${TEST_INDEX} | テストの連番 |
| ${FILE_INDEX} | フィルの連番 |
| ${QUARANTINE_ATTEMPT} | 検疫の実施番号（？）。検疫モードでない場合は「1」が設定されるらしい |
| ${FIXTURE} | fixture名。テストAPIで記述した「fixture」の名前 |
| ${TEST} | テスト名。テストAPIで記述した「test」の名前 |
| ${USERAGENT} | 後述のブラウザ名、ブラウザのバージョン、OS名、OSのバージョンを結合したもの |
| ${BROWSER} | ブラウザ名 |
| ${BROWSER_VERSION} | ブラウザのバージョン |
| ${OS} | OS名 |
| ${OS_VERSION} | OS名のバージョン |
| ${TEST_ID} | 「test-${TEST_INDEX}」に同じ。 |
| ${RUN_ID} | 「run-${QUARANTINE_ATTEMPT}」に同じ。 |


　タイムアウトの基本設定ができるようです。この値は実際のテストの際に変更できます。たとえばページロードで1画面だけ極端に時間がかかる場合はその時だけタイムアウトを大きくするといいと思います。テスト時の設定は次回で。
　コマンドラインの色の利用って何かと思ったら、エラーメッセージなどに色を付けるということでした。オフにすると見にくいかな。

　またしばらく間があくかもしれませんが、次回はテストの記述に関わる調査をしてその結果とちょっと思うところがあるのでそのあたりの記述をします。