E2Eテストについてちょこちょこ調べていて、ブラウザ操作の自動化でSelenium以外に何かないかなと思っていたら、TestCafeが割と良さそうだったのでメモ。
環境
TestCafe v1.10.0。
インストールにはNode.js v14.15.2、およびYarn v1.22.5を使用。
TestCafeとは
JavaScriptまたはTypeScriptで実装できるE2Eテストツール。
インストールすればすぐに使え、Seleniumのように各ブラウザごとのドライバーなど用意しなくても動かせるのがメリット。
インストール
npmなら npm install -g testcafe 、Yarnなら yarn global add testcafe でグローバルインストールする。
testcafe -v でバージョン表示、 testcafe -b で、利用可能なブラウザ一覧を確認できる。
Firefox、Google Chrome、Chromium版Microsoft Edge、おまけでIE11の入ったWindows 10では、インストール時点で以下のように表示される。
$ testcafe -b
Using locally installed version of TestCafe.
firefox
chrome
ie
edge
テスト実行
コマンドラインから実行する場合、 testcafe [-c 並行実行数] [実行するブラウザ] テスト実装ファイル 。
ブラウザは firefox,chrome,ie のように、カンマ区切りで複数実行可能。 firefox および chrome は、それぞれ firefox:headless および chrome:headless と記述することで、ヘッドレスモードでも実行できる。
また、 -c 並行実行数 を指定することで、並行実行も可能。
この他にも、後述のFixture名でフィルタリングしたりできる模様。
JavaScriptからの実行
APIを使用して、JavaScriptからも実行できる。
const createTestCafe = require('testcafe'); const testcafe = await createTestCafe(); const runner = testcafe.createRunner(); await runner .src(['tests/fixture1.js', 'tests/fixture2.js']) .browsers(['firefox', 'chrome:headless', 'ie']) .concurrency(3) .run();
テスト実装
fixtureとtest
テストファイル内に1つ以上のfixtureを、また1つのfixtureにつき1つ以上のtestを記述する。
fixture `MyFixture`; test('Test1', async t => { // テストコードを記述 });
fixture, test、どちらでも、 page で実行する際のURLを指定できる。fixtureにpageを指定すると、そのfixtureに含まれるすべてのtestがそのURLを開いた状態で実行される。testでpageを指定することで、fixtureのURLを上書きできる。
fixture `MyFixture`
.page `https://google.com`;
test('Test1', async t => {
// Googleで実行される
});
この他、meta でメタ情報を付与したり、fixtureには beforeEach および afterEach 、testには before および after で前処理/後処理を記述したりできる。
TestController
testの第2引数で渡している関数の引数、 t の実体はTestControllerというクラス。
文字の入力、クリック、エンター押下などはTestControllerを通して行う。
また、 ctx プロパティにKey-Valueで値を設定することで、fixtureとtest間や、testのbeforeとテストコード間などで値の共有が可能。
Selector
HTMLの要素の取得などは、Selectorを使用する。
以下の記述より、SelectorはTestControllerのメソッドに渡されたり、アサート対象になったタイミングで、遅延評価される模様。
The selector value is evaluated each time you :
- use the selector for an action;
- assert selector’s properties;
- call the selector directly in code to get it’s state;
Assert
TestControllerのメソッドとして、Assert用のメソッド expect が用意されている。
expect にactualを渡し、メソッドチェーンで比較用メソッドを実行して期待値を渡す。
expect に渡された値が、Selectorで取得したDOMノードやPromiseの場合、動的ページに対応するために、テストが失敗してもすぐにエラーにはならず、タイムアウトまで複数回実行されるとのこと。Smart Assertion Queryと呼ばれている。
Page Object Pattern
サンプルを見るとほとんど手続き的にテストを書いているが、Page Object Patternでも記述できる模様。
振り返り
ちょっと試したが、なんといっても複数ブラウザでの実行が、Seleniumに比べると非常に楽。
タイムアウトまで再試行というのは、素のSeleniumを使っているならいざ知らず、Selenideのようなラッパーを使っていれば対応できるので、あまりメリットには感じなかった。
一方、やや不便に感じたのは、非同期処理には async/await を使用しているため、都度記述するのが面倒。これは慣れるしかないか。
セットアップや複数ブラウザ対応が楽というのは、運用開始時にはプラスになるが、運用が始まればあまり意味がなくなるので、既にSeleniumなどのE2Eテスト資産があれば乗り換えるメリットはないが、新規でE2Eテスト環境を構築しようと思っているのであれば十分候補になるかと思った。