今回はCodeceptJSでのHelperの作り方について紹介していきます。
Helperとは?
CodeceptJSの基本機能でフロントエンドテストは大体できますが、バックエンドテストを行うのは厳しいです。
Node.jsのライブラリを利用することでメールのチェックなどのテストを行えます。
ですが、テストコード内でコーディングしてしまうと可読性が下がってしまいます。
そこで用意するものがHelperです。
公式リファレンスでは以下のように説明されています。
Helper is a wrapper on top of various libraries providing unified interface around them.
「Helperはライブラリのラッパーとして活躍してくれるやつだぜ!(意訳)」
というわけで、ラッパークラスという名のHelperを作っていきましょう。
Helperを作成してみよう
前回の記事で使ってみたJSON Server用のhelperを作っていきます。
前回の手順ではテスト実行前にJSON Serverを手動で起動しておく必要があり、
また終了させるのにも手動で行わなければいけませんでした。
これだとJSON Serverの起動し忘れなどのミスが発生してしまう可能性があるので、
テスト開始時にJSON Serverを起動して、テスト終了時に停止するようなHelperを作成してみましょう。
JSON Serverのインストール
npm install json-server
Helperファイルの作成
npx codeceptjs init
でCodeceptJSの実行なファイルを作成します。
各設定項目についてはこちらの記事を参考にしてください。
npx codeceptjs gh
コマンドを実行するとHelper作成用の対話コンソールが起動します。
各設定項目はテキトーでOKです。
npx codeceptjs gh Creating a new helper -------------------------- ? Name of a Helper jsonServer ? Where should it be stored ./jsonserver_helper.js Helper for JsonServer was created in C:\Dev\helperCreate\jsonserver_helper.js Update your config file (add to helpers section): helpers: { JsonServer: { require: './jsonserver_helper.js', }, },
作成が完了すると、設定ファイルのHelpersセクションに設定項目を追加しろ!と言われます。
「codecept.conf.js」ファイルに追記
「codecept.conf.js」を開き、Helpersセクションに追記しましょう。
あとついでにREST機能も利用するので16~27行目の設定項目を追加して保存してください。
const { setHeadlessWhen } = require('@codeceptjs/configure'); // turn on headless mode when running with HEADLESS=true environment variable // export HEADLESS=true && npx codeceptjs run setHeadlessWhen(process.env.HEADLESS); exports.config = { tests: 'sample/*_test.js', output: './output', helpers: { Playwright: { url: 'http://localhost', show: true, browser: 'chromium' }, JsonServer: { require: './jsonserver_helper.js', url: 'http://localhost', port: 3000, }, REST: { endpoint: 'http://localhost:3000', defaultHeaders: { 'Content-Type': 'application/json' }, onRequest: (request) => {}, }, }, include: { I: './steps_file.js' }, bootstrap: null, mocha: {}, name: 'helperCreate', translation: 'ja-JP', plugins: { pauseOnFail: {}, retryFailedStep: { enabled: true }, tryTo: { enabled: true }, screenshotOnFail: { enabled: true } } }
Helperファイルの確認
Helper作成用の対話コンソールで作成されたHelperファイルを開いてみましょう。
すると_beforeメソッドと_afterメソッドが用意されています。
_beforeメソッドは1つのテストシナリオの開始前に実行され、
_afterメソッドは1つのテストシナリオ終了後に実行されます。
const Helper = require('@codeceptjs/helper'); class JsonServer extends Helper { // before/after hooks /** * @protected */ _before() { // remove if not used } /** * @protected */ _after() { // remove if not used } // add custom methods here // If you need to access other helpers // use: this.helpers['helperName'] } module.exports = JsonServer;
他のHook達
_before、_after以外にも用意されています。
_init | 全テスト開始前。最初に1度だけ呼ばれるやつ。コンストラクタ的なイメージ。 |
_finishTest | 全テスト終了後。最後に1度だけ呼ばれるやつ。デストラクタ的なイメージ。 |
_beforeSuite | 各スイートの実行前。1ファイル = 1スイート的なイメージでOK。 |
_afterSuite | 各スイートの実行前後。 |
_passed | テストシナリオ成功時。 |
_failed | テストシナリオ失敗時。 |
_before | テストシナリオ開始前。テストシナリオの数だけ実行される。 |
_after | テストシナリオ終了後。 |
_beforeStep | テストステップ実行前。ステップ数だけ実行される。 |
_afterStep | テストステップ実行後。ステップ数だけ実行される。 |
db.jsonの作成
JSON Serverで利用するためのdb.jsonを作成します。
ルートディレクトリにファイルを作成し、以下の値をコピペして保存してもらうだけでOKです。
{ "posts": [ ], "comments": [], "profile": { "name": "typicode" } }
JsonServerHelperのコーディング
さて、実際にHelperを作成していきましょう。
以下のコードをHelperファイルに入力してください。
const Helper = require('@codeceptjs/helper'); const jsonServer = require('json-server'); class JsonServer extends Helper { constructor(config) { super(config); this.server = jsonServer.create(); this.router = jsonServer.router('db.json'); this.middlewares = jsonServer.defaults(); } _init() { // JSON Server起動 this.server.use(this.middlewares); this.server.use(this.router); if (process.argv[2] === 'def') { return; } this.executionJsonServer = this.server.listen(this.config.port, () => { console.log('JSON Server is running') }); } _finishTest() { // 全てのテストが終了したらJSON Serverを停止する this.executionJsonServer.close(); } } module.exports = JsonServer;
今回は_beforeと_afterは利用しないので削除しました。
_initを利用してテスト開始時にJSON Serverを起動し、_finishTestを利用してテスト終了時にJSON Serverを停止させています。
動作確認
さて、実際に作成したHelperが動作しているのか、テストコードを作成・実行して確認してみましょう。
REST APIを利用してJSON Serverに値を登録し、登録された内容を取得しています。
npx codeceptjs run
コマンドで実行します。
Feature('JSON Server'); Scenario('REST APIで動作確認', async ({ I }) => { // ダミーデータを作成 await I.sendPostRequest('/posts', {'id': '', "title": "posted from node-webhooks"}); // JSON Serverに登録されたデータを確認する let result = await I.sendGetRequest('/posts?title=posted from node-webhooks'); console.log(result.data); });
実行結果
正常に実行できたら、以下のような実行結果が表示されているはずです。
JSON Server -- POST /posts 201 21.808 ms - 53 GET /posts?title=posted%20from%20node-webhooks 200 21.517 ms - 65 [ { title: 'posted from node-webhooks', id: 1 } ] √ REST APIで動作確認 in 76ms
テスト開始前にデータクリア
大体、Helperの作成は終わりましたが、
このままだとこのテストコードを実行する度にデータが増えていってしまいます。
今回はスイートごとでデータをクリアする想定で、_beforeSuite(_afterSuiteでも可)を利用して以下のコードを追記してみましょう。
登録済みのデータを全て取得して、取得数分だけ削除リクエストを送っています。
async _beforeSuite() { const jsonServerUrl = `${this.config.url}:${this.config.port}/posts`; let result = await this.helpers['REST']._executeRequest({ method: 'GET', url:jsonServerUrl, }); await Promise.all(result.data.map(async (data) => { this.helpers['REST']._executeRequest({ method: 'DELETE', url:jsonServerUrl + '/' + data.id, }); })); }
まとめ
メールチェック、Webhookチェック、データベースチェックなどなどチェックする対象はいくらでもあります。
システムごとに必要となるHelperを作成してE2Eテストを効率的に進めてみましょう!
雑記
E2Eテストの目的は手動テストの自動化が主目的ではなく、デグレーションの検知が主目的だと考えています。
ちゃんとフロントとバックの隅々まで確認し、デグレを阻止しましょう!