🅿️

PlaywrightとCSVでデータ駆動テストを作成する

2024/03/30に公開

はじめに

今回はE2Eテストツール「Playwright」とCSVファイルを使い、
データ駆動テスト(Data Driven Testing)を作成してみます!

データ駆動型のテストは、正常なデータ、異常なデータ、境界値のデータなど、
1つのシナリオで入力値をいろいろ変えてテストしたい場合に役立ちます。

作成するテストの対象はデモ用のToDo管理アプリで、
以前作成したテストをもとに、データ駆動に変えたいと思います。

https://zenn.dev/collabostyle/articles/482bb93bf3bd89

修正前のテストコード

以下が、以前Playwrightのテストジェネレーターで作成したコードです。

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://demo.playwright.dev/todomvc/#/');
  await page.getByPlaceholder('What needs to be done?').fill('task A');
  await page.getByPlaceholder('What needs to be done?').press('Enter');
  await expect(page.getByTestId('todo-title')).toBeVisible();
  await page.getByPlaceholder('What needs to be done?').click();
  await page.getByPlaceholder('What needs to be done?').fill('task B');
  await page.getByPlaceholder('What needs to be done?').press('Enter');
  await expect(page.locator('body')).toContainText('task B');
  await page.locator('li').filter({ hasText: 'task A' }).getByLabel('Toggle Todo').check();
  await expect(page.locator('li').filter({ hasText: 'task A' }).getByLabel('Toggle Todo')).toBeChecked();
});

「task A」と「task B」をタスク登録していますが、コードが冗長ですね。。

データ駆動のテストコード

CSVファイルを作成する

先ずはinput.csvを作成し、以下のテストデータを記入します。

"name","completed"
"task A","false"
"タスク B","true"

タスク名は半角と全角文字にしてみました。
completedがtrueの場合、完了状態のタスクにします。

修正後のテストコード

Playwrightのドキュメント「Parameterize tests」を参考に、以下のように修正してみました!
CSVファイルのテストデータを読み込み、ループでテストを実行する処理になっています。

import { test, expect, Page } from '@playwright/test';
import fs from 'fs';
import path from 'path';
import { parse } from 'csv-parse/sync';

const csvFile = 'input.csv';
const tasks = parse(fs.readFileSync(path.join(__dirname, csvFile)), {
  columns: true,
  skip_empty_lines: true
});

const appUrl = 'https://demo.playwright.dev/todomvc/#/';

test.describe('ToDoアプリのテスト', () => {
  let page: Page;

  test.beforeAll(async ({ browser }) => {
    page = await browser.newPage();
    await page.goto(appUrl);
  });

  for (const input of tasks) {
    const inputCompleted = input.completed === 'true';

    test(`タスク「${input.name}」の登録`, async () => {
      // タスク名の入力
      await page.fill('.new-todo', input.name);
      await page.keyboard.press('Enter');

      // タスクが完了状態であればチェックを入れる
      if (inputCompleted) {
        await page.check('.todo-list input.toggle');
      }
    });

    test(`タスク「${input.name}」の表示確認`, async () => {
      // タスク名の表示を確認
      const taskElement = await page.waitForSelector('.todo-list label');
      expect(await taskElement.innerText()).toBe(input.name);

      // タスの完了状態を確認
      const taskToggle = await page.waitForSelector('.todo-list input.toggle');
      expect(await taskToggle.isChecked()).toBe(inputCompleted);
    });
  }
});

処理の解説

CSVファイルの読み込み

CSVのテキストデータをオブジェクトに変換ライブラリ「csv-parse」を利用しています。
package.jsonに「csv-parse」を追加して、インストールしましょう。

parse(fs.readFileSync(path.join(__dirname, csvFile)), {...}の処理で、
テストデータを配列にしています。

テストの前処理

test.beforeAll()で、テストの前処理としてToDo管理アプリにアクセスしています。
beforeAll()は、テストのワーカープロセス毎に1回実行されます。

Playwrightはデフォルトで並列実行されるため、今回のデータ駆動では
テストデータのループ毎にToDo管理アプリにアクセスします。
つまり1画面で、1件ずつ登録するテストになります。

データ駆動のテスト

テストデータをもとに、for文でテストがループ(並列)実行されます。
テストは「タスクの登録テスト」と、登録後の「表示確認テスト」で分けてみました。

タスクの登録には、CSVで定義したデータ(name,completed)が使われます。
画面要素を示すselector(locator)も、分かりやすいclass指定に修正しています。

おわりに

データ駆動テストでは、様々な入力値を使い反復的に実行することで、網羅的に検証できます。
また、入力値はCSVファイルにすることで、メンテナンス性が向上します。
入力値を変えた多様なテストが必要な場合、データ駆動は便利ですね😉

コラボスタイル Developers

Discussion