Node.js製のe2eテストツール TestCafeを試す
2019.02.13
こんにちは。
ユニトラストでエンジニアをしている我妻です。
以前にe2eテストをSeleniumでやろうとした時に環境構築で大分時間が取られ挫けそうになった経験があり、
フロントエンドのテストを行える手軽に使えるテストツールはないかといくつか試している中で公式サイトでも「1分でセットアップ」と謳っており、
実際に触って便利だなと思ったTestCafeの紹介です。
なお、今回動かしているコードサンプルはGitHubに置いてあります
testcafe-e2e-sample
TestCafeとは
TestCafeとはNode.js製のe2e自動テストツールで実行ホストに関わらず動作させることができ、主要ブラウザに対してならwebdriver等の導入も不要でテストを行う事ができます。同名のwebサービスも展開されていますが、今回取り扱うのはMITライセンスで公開されている開発者向けテストツールになります。
動作環境
今回動作させた環境は以下の通りです。
- Windows10 Pro build 17763.253
- Node.js v10.15.0
- npm 6.4.1
- TestCafe 0.23.3
実際に動かす
今回のコード構成は下記の通りです
/ ├─report ├─screenshot └─tests ├─features │ └─testcafe └─pages └─testcafe
Page Object Model
TestCafeはPage Object Modelに対応しているため、それに準拠した形でページ構成・挙動を管理するPageと実テストをつかさどるFeatureに分けています。
場合によってはPageの操作部分を更にOperationとして分離させるケースもあるようですが、今回は簡便化のためにそこまでは行いません。
Demo
解説
今回は2通りのテストパターンを盛り込んでいます。
1つ目がGoogle検索にてワード検索を行い、検索結果から期待したサイトに遷移できるか、
2つ目がサイト内の移動と要素の表示状態の検査となります。
Google検索
export default class TopPage { constructor () { this.url = 'https://www.google.co.jp/'; this.inputSearchBox = Selector('.gLFyf.gsfi'); this.buttonSearch = Selector('input[name="btnK"]'); this.buttonFeelingLucky = Selector('input[name="btnI"]'); }
ページ構成要素宣言部です。
HTMLでのセレクタと同じように記述することができるので、javascript等でなれている人は特に違和感なく記述することができるのではないでしょうか。
/** * 検索実行 */ async search(text) { await t.typeText(this.inputSearchBox, text) .click(this.buttonSearch); }
画面の振る舞いをメソッドとして定義していきます。
連続した操作の場合はメソッドチェーンとして記述していくことができます
/** * Google検索→検索結果表示->詳細クリック */ test('Google検索', async (t) => { const searchWord = 'Example Domain'; await topPage.search(searchWord); await listPage.showDetail(searchWord); const actualUrl = ClientFunction(() => window.location.href); const expectedUrl = 'https://example.com/'; await t.takeScreenshot(); await t.expect(actualUrl()).eql(expectedUrl); });
実際のテストメソッドの記述はこのようになります。
先程定義したPage Objectの振る舞いを順に呼び出していきます。
仮に画面の構成要素が移動したり名称が変わったりしてもテストコード自体には影響が出にくいのがPage Object Modelの良いところですね。
フォーム入力・サイト内移動
続いてTestCafeで用意されているサンプルページでの動作テストです。
Page Object側については特に変わらないので割愛します。
// ページタイトル await t.expect(Selector('title').innerText).eql(examplePage.pageTitle); // コメント入力欄が非活性状態 await t.expect(examplePage.textAreaComment.hasAttribute('disabled')).ok(); // Submit ボタンが非活性状態 await t.expect(examplePage.buttonSubmit.hasAttribute('disabled')).ok();
こちらのテストコードについては初期表示時に非活性になっている項目が存在しているため、状態のチェックを挟んでいます。
出力レポートについてはJenkins等のCIツールと連携しやすいようにxUnit形式のレポートファイルを出力するようにしています。
また公式でDockerイメージを配布しているため、これを利用することにより更に開発環境に左右されないe2eテストを実施することができるようになります。
こういったテストをプロジェクトで導入しようとすると事前準備の面倒さで躓く事が多いのでNode.jsさえあれば簡単に導入できるのは強みですね。
CONTACT
お問い合わせ
あなたの「想い」に挑戦します。
どうぞお気軽にお問い合わせください。
受付時間:平日9:00〜18:00 日・祝日・弊社指定休業日は除く