kintoneで、E2Eテストをやってみた
kintoneでE2Eテストをしてみる
弊社では、kintoneのアプリが30個以上を超えてきてまた
カスタムJSもかなり複雑になってきていて何かを変更した時に
うまくレコードが作成されないなど品質的な部分での悩みが増えてきました。
まだ、テストが一切なく手動で確認しているので、E2Eテストをちょっと触ってみました。
何ができるのか
kintoneの自動ログイン、kitoneのアプリ画面でフィールド入力、レコード保存、編集、画面確認など
ユーザが操作することは基本的にできます!!
「E2Eテスト」とは?
E2Eテストとは、1つのアプリケーションに対し「複数のユーザーワークフローでシミュレーションを実施し、そのパフォーマンスを測るもの」です。E2Eテストが、単体テストや結合テストといったほかのテストと異なるのは、ユーザーのワークフロー全体にフォーカスしている点です。E2EとはEnd-to-End(端から端まで)の略
何を使うか
jinzo-ningen
GitHub - goqoo-on-kintone/jinzo-ningen
jinzo-ningen は、puppeteer による kintone 操作を補助する Node.js 用ライブラリです。
Puppeteerは、Node.jsライブラリで、Headless ChromeやChromiumブラウザを制御するために使用されます。
Headlessブラウザは、グラフィカルユーザーインターフェイス(GUI)を持たないブラウザで、通常は自動化されたタスクやテストの実行に使用されます。Puppeteerは、これらのブラウザをプログラムで制御し、Webページの操作、スクリーンショットの取得、フォームの入力、ページのナビゲーション、Webスクレイピングなどを行うことができます。
設定
基本的には以下のREADMEとチュートリアル通りに設定を行なっていきます。
jinzo-ningen・jest・jest-puppeteerをインストール
npm add --save-dev jinzo-ningen jest jest-puppeteer
# or
yarn add --dev jinzo-ningen jest jest-puppeteer
jest.config.js
の作成
module.exports = {
preset: 'jest-puppeteer',
}
プロジェクトのルートに下記の内容で jest-puppeteer.config.js
を保存します。
ここでは headless
に false
を設定し、テスト時に headless ではない Chromium を表示して挙動を確認します。
module.exports = {
launch: {
// headless ではない Chromium を使用する。デフォルトは true
headless: false,
},
}
package.json
に下記のエントリを追加します。
"scripts": {
"test": "jest"
},
任意のディレクトリを作成する。
mkdir jinzo-ningen-test
cd jinzo-ningen-test
mkdir __tests__
実装
jinzo-ningen-test/__tests__配下に以下testファイルを作成
では実際のテストを記載していきます!
注意 README通りにログインを変更前で記載するとログインできなかったので
変更後で記載するとログインできました。
// テストのセットアップ。ここで kintone へのログインを行う
変更前
beforeAll(async () => {
// global.page オブジェクトは jest-puppeteer が自動的にロードしている
await page.setViewport({ width: 1920, height: 980 });
// kintone にログイン(domain, username, password が必要)
await jz.login({ domain, username, password });
});
変更後
beforeAll(async () => {
await page.setViewport({ width: 1920, height: 980 });
await page.goto(`https://${domain}/login`);
await page.type('input[name="username"]', username);
await page.type('input[name="password"]', password);
await page.click('input.login-button');
await page.waitForNavigation();
});
kintoneにログインのためのコード
index.test.jsを作成
const jz = require('jinzo-ningen');
// テスト全体のタイムアウト時間を設定(単位:ミリ秒)。
jest.setTimeout(60 * 1000);
// テストの記述
describe('レコード作成テスト', () => {
// ログイン情報はテストする kintone 環境、アプリに置き換える
const domain = '設定のドメイン';
const username = 'ログインユーザー名';
const password = 'パスワード';
const appId = アプリID;
// テストのセットアップ。ここで kintone へのログインを行う
beforeAll(async () => {
await page.setViewport({ width: 1920, height: 980 });
await page.goto(`https://${domain}/login`);
await page.type('input[name="username"]', username);
await page.type('input[name="password"]', password);
await page.click('input.login-button');
await page.waitForNavigation();
});
// ログインが成功したことを確認するテスト
it('ログインが成功すること', async () => {
// kintone アプリのホーム画面が表示されていることを確認
await expect(page).toMatch('kintone');
});
});
下記のコマンドでテストを実行します。
npm test
コマンドを実行すると、自動でログイン画面が表示され
ログインが成功したはずです!!
流れとしては、レコード作成画面で対象のフィールドに値を入れ保存し
レコード作成後、詳細画面に遷移が成功したことをテストしています。
今回操作するフィールド
- 文字列(一行)
- ルックアップ
- 文字列(複数行)
- 数値
- ドロップダウン
- 日付
const jz = require('jinzo-ningen');
// テスト全体のタイムアウト時間を設定(単位:ミリ秒)。
jest.setTimeout(60 * 1000);
// テストの記述
describe('レコード作成テスト', () => {
// ログイン情報はテストする kintone 環境、アプリに置き換える
const domain = '設定のドメイン';
const username = 'ログインユーザー名';
const password = 'パスワード';
const appId = アプリID;
// テストのセットアップ。ここで kintone へのログインを行う
beforeAll(async () => {
await page.setViewport({ width: 1920, height: 980 });
await page.goto(`https://${domain}/login`);
await page.type('input[name="username"]', username);
await page.type('input[name="password"]', password);
await page.click('input.login-button');
await page.waitForNavigation();
});
// ログインが成功したことを確認するテスト
it('ログインが成功すること', async () => {
// kintone アプリのホーム画面が表示されていることを確認
const content = await page.content();
await expect(content).toMatch('kintone');
});
// レコード作成画面への遷移をテストするdescribeブロック
describe('レコード作成画面', () => {
beforeAll(async () => {
await jz.gotoCreatePage(domain, appId);
});
// レコード作成画面が表示されていることを確認するテスト
it('レコード作成画面が表示されること', async () => {
// テキスト
await jz.setSingleLineText('支払先名_取引先マスタ', "test株式会社");
// ルックアップ
await jz.setLookup('支払先名_取引先マスタ', 'test株式会社');
// 複数文字
await jz.setMultiLineText('金額明細', "test");
// 数値
await jz.setNumber('税抜金額', 1000);
// ドロップダウン
await jz.selectDropdown('支払サイト', '25日_月末締め翌月25日');
// レコードを保存して詳細画面が表示されることを確認
await jz.pressSaveAndWaitForDetailScreen();
const detailContent = await page.content();
await expect(detailContent).toMatch('レコードの詳細'); // 適切な確認テキストを指定してください
});
});
});
これでテストが成功しました!
Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 11.151 s, estimated 13 s
Ran all test suites.
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect...
まとめ
今回kintoneのjinzo-ningen のライブラリを利用して、E2Eテストを実施してみました。
全てのテストケースを網羅するのは、難しいので標準的な正常系だけでも
テストするのは品質を担保するには良いかなと思いました!
Discussion