Page Object PatternをベースにTestCafeでE2Eテストを作ってみた
以前のエントリでKotlinでSelenideを使ったE2Eテストを作ったときもPage Object Patternを利用して見通しの良いテストコードが書けました。TestCafeでも同様にPage Object Patternを利用することが推奨されています。
今回はTestCafeでもPage Object Patternを利用してテストを書いてみました。
何をテストするか
次のサイトのログイン認証をテストします。
テスト内容としては次のとおりです。
- 認証画面のURLを開く
- IDとパスワードを入力する
- ログインボタンをクリックする
- ログインが完了するとHome画面にリダイレクトされるので正しくリダイレクトされているか
- ログインが完了するとヘッダーモジュールにアカウント名が表示されてるので正しく表示されているか
テストコードのフォルダ構成
プロジェクトのフォルダ構成は次のように役割ごとに整理しました。
tests ├── features ├── operators ├── pages └── support
- featuresにはスペックコードをまとめます。
- operatorsにはPageオブジェクトから画面要素を参照してログインボタンをクリックするなどのオペレーションをまとめます。
- pagesには画面の要素を参照できるようなPageオブジェクトを画面ごとにまとめます。今回は認証画面とHome画面をPageクラスにしました。
- supportにはスペックコードでテストを進めるときに画面キャプチャを撮るなどのユーティリティ機能をまとめます。
次からはTestCafeのAPIを利用して記述したコード例を紹介します。
Pageクラス
TestCafeのAPIを利用して認証画面のPageクラスを作ります。
import { Selector } from 'testcafe'; export default class AuthPage { constructor () { this.url = 'https://freshlive.tv/auth/fresh_id'; this.idInput = Selector('#user_id'); this.pwInput = Selector('#password'); this.submitBtn = Selector('button[type=submit]'); } }
- 認証画面のURLを変数に定義する。
- テストに必要な画面要素はSelectorを利用して定義する。
- idInputはログインID、pwInputはパスワードの入力フィールドです。
- submitBtnはログインボタンです。
これで認証画面の要素をまとめたAuthPageクラスができあがりました。
Operatorクラス
TestCafeのAPIを利用してOperatorクラスを作ります。
今回は認証画面でログイン認証する必要があるのでログイン操作をまとめます。
import {t} from 'testcafe'; import AuthPage from '../../pages/auth/auth-page.js'; export default class AuthOperator { constructor () { this.page = new AuthPage(); } async open() { await t .navigateTo(this.page.url) } async authorize(id, password) { await this.open(); await t .typeText(this.page.idInput, id) .typeText(this.page.pwInput, password) .click(this.page.submitBtn) } }
- constructor ()でAuthPageクラスからPageオブジェクトを生成します。
- authorize(id, password)では認証画面を開きIDの入力とパスワードの入力を行い最後にログインボタンをクリックしています。typeTextとclickで入力とクリックの操作ができます。
- tはTestCafeのTestConrollerオブジェクトです。async-awaitとimportをすることでテスト実行時のTestConrollerオブジェクトと同期できます。0.13.0のリリース(Using test controller outside of test code (#1166))でTestConrollerをテストコード外でも参照することができるようになりました。(いいね!)
Supportクラス
TestCafeのAPIを利用してのSupportクラスを作ります。
今回は画面キャプチャを撮るユーティリティクラスを作りました。
import {t} from 'testcafe'; export default class ScreenshotSupport { constructor () { } async take() { await t .takeScreenshot; } }
Specクラス
TestCafeのAPIを利用してのSpecクラスを作ります。
このクラスでテスト内容をまとめていきます。
import { expect } from 'chai'; import HomePage from '../../pages/home/home-page.js'; import AuthOperator from '../../operators/auth/auth-operator.js'; import ScreenshotSupport from '../../support/screenshot-support.js'; const homePage = new HomePage(); const authOperator = new AuthOperator(); const screenshot = new ScreenshotSupport(); const userId = ' xxxxxxxx'; const password = 'xxxxxxxx'; const accountId = 'My Account'; fixture `auth fixtures`; test('authorized at page then is appeared your account name on element of header.', async t => { // ログインする await authOperator.authorize(userId, password); // スクリーンショット撮る await screenshot.take(); // ログイン後にHomeにリダイレクトをするのでURLが正しく切り替わっているか const docURI = await t.eval(() => document.documentURI); expect(docURI).eql(`${homePage.url}?&login_succeeded=true`); // ヘッダーメニューにログインしたアカウント名が表示されているか await t .expect(homePage.accountMenuDropdown.exists).eql(true) .expect(homePage.accountName.exists).eql(true) .expect(homePage.accountName.innerText).eql(accountId); });
- fixtureはテストをカテゴライズする機能でテスト実行時にfixtures単位でテストを実行するオプションがあります。
- testではテストのタイトルとテストコードを記述していきます。
- Operatorクラスでまとめた認証画面でログインするauthorize(userId, password)を呼びだしてログインを実行しています。
- ログイン後にURLが切り替わっているかdocURI変数にURLを入れてチェックしています。
- 最後にexpectを利用してヘッダーモジュールにアカウント名が表示されているかをチェックしています。