T-CREATOR

Playwright の Recorder 機能でテスト作成がここまで楽に!

Playwright の Recorder 機能でテスト作成がここまで楽に!

テスト自動化というと、多くの方が「難しい」「時間がかかる」「学習コストが高い」と感じているのではないでしょうか。特に、手動でテストコードを書く作業は、初心者にとって大きな壁となっています。

しかし、Playwright の Recorder 機能を使えば、その常識が一変します。ブラウザで操作するだけで、自動的にテストコードが生成されるという驚きの機能なのです。

この記事では、Playwright Recorder の魅力と実践的な使い方を詳しく解説していきます。あなたも、この機能を使えば、今まで数時間かかっていたテスト作成が数分で完了するようになるでしょう。

Recorder 機能とは

Playwright Recorder は、ブラウザでの操作を自動的に記録し、テストコードを生成してくれる画期的な機能です。従来のテスト作成方法とは一線を画す、革新的なアプローチを提供します。

従来のテスト作成との違い

従来のテスト作成では、以下のような手順が必要でした:

  1. テスト対象の要素を調査
  2. セレクターを手動で特定
  3. テストコードを一から記述
  4. アサーションを追加
  5. エラーハンドリングを実装

これに対して、Recorder 機能では:

  1. ブラウザで実際に操作するだけ
  2. 自動的にテストコードが生成される
  3. 必要に応じてコードを調整

この違いは、まさに革命的なものです。

Recorder 機能の仕組み

Recorder 機能は、以下のような仕組みで動作します:

javascript// Recorderが自動生成するコードの例
const { test, expect } = require('@playwright/test');

test('ログインテスト', async ({ page }) => {
  // ページにアクセス
  await page.goto('https://example.com/login');

  // ユーザー名を入力
  await page.getByLabel('ユーザー名').fill('testuser');

  // パスワードを入力
  await page.getByLabel('パスワード').fill('password123');

  // ログインボタンをクリック
  await page
    .getByRole('button', { name: 'ログイン' })
    .click();

  // ログイン成功の確認
  await expect(page.getByText('ようこそ')).toBeVisible();
});

このように、人間が理解しやすい自然なコードが自動生成されます。

環境構築とセットアップ

Playwright Recorder を使用するための環境構築を行いましょう。Node.js がインストールされていることを前提として進めます。

1. プロジェクトの初期化

まず、新しいプロジェクトディレクトリを作成し、初期化します:

bash# プロジェクトディレクトリを作成
mkdir playwright-recorder-demo
cd playwright-recorder-demo

# package.jsonを初期化
yarn init -y

2. Playwright のインストール

Playwright とその依存関係をインストールします:

bash# Playwrightをインストール
yarn add -D @playwright/test

# ブラウザをインストール
npx playwright install

3. 設定ファイルの作成

Playwright の設定ファイルを作成します:

javascript// playwright.config.js
const { defineConfig } = require('@playwright/test');

module.exports = defineConfig({
  testDir: './tests',
  timeout: 30000,
  expect: {
    timeout: 5000,
  },
  use: {
    headless: false,
    viewport: { width: 1280, height: 720 },
    ignoreHTTPSErrors: true,
    video: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

4. よくあるエラーと解決方法

環境構築時に発生しがちなエラーを紹介します:

エラー 1: Node.js のバージョンが古い

bash# エラーメッセージ例
Error: Node.js version 14.0.0 is not supported. Please use Node.js 16.0.0 or higher.

# 解決方法
node --version  # バージョン確認
# Node.js 16以上にアップデートが必要

エラー 2: ブラウザのインストールに失敗

bash# エラーメッセージ例
Error: Failed to install browsers
Error: EACCES: permission denied

# 解決方法
sudo npx playwright install  # macOS/Linuxの場合

Recorder 機能の基本的な使い方

環境構築が完了したら、実際に Recorder 機能を使ってみましょう。

Recorder の起動方法

Recorder を起動するには、以下のコマンドを実行します:

bash# Recorderを起動
npx playwright codegen

このコマンドを実行すると、2 つのウィンドウが開きます:

  1. ブラウザウィンドウ: 実際に操作を行うウィンドウ
  2. コード生成ウィンドウ: 生成されるテストコードを表示するウィンドウ

基本的な操作手順

Recorder の基本的な使い方を説明します:

javascript// 1. ブラウザで操作を行う
// 2. 操作が自動的にコードとして記録される
// 3. 生成されたコードをコピーしてテストファイルに保存

// 生成されるコードの例
const { test, expect } = require('@playwright/test');

test('基本的な操作テスト', async ({ page }) => {
  await page.goto('https://example.com');
  await page.getByRole('link', { name: 'About' }).click();
  await expect(page).toHaveURL('https://example.com/about');
});

Recorder の便利な機能

Recorder には、以下のような便利な機能があります:

1. セレクターの自動生成

javascript// 複数のセレクター候補が自動生成される
await page.getByRole('button', { name: 'Submit' }).click();
await page.locator('button:has-text("Submit")').click();
await page.locator('[data-testid="submit-button"]').click();

2. アサーションの自動追加

javascript// 操作後に自動的にアサーションが追加される
await page.getByRole('button', { name: 'Login' }).click();
await expect(page.getByText('Welcome')).toBeVisible();

実際のテスト作成手順

それでは、実際にテストを作成する手順を詳しく見ていきましょう。

1. テスト対象の Web サイトを開く

まず、テスト対象となる Web サイトを決定します。この例では、一般的なログインフォームをテスト対象とします。

bash# Recorderを起動して特定のURLから開始
npx playwright codegen https://example.com/login

2. テストシナリオを記録する

ブラウザで実際の操作を行い、テストシナリオを記録します:

javascript// 記録される操作の例
const { test, expect } = require('@playwright/test');

test('ログインフロー', async ({ page }) => {
  // 1. ログインページにアクセス
  await page.goto('https://example.com/login');

  // 2. ユーザー名を入力
  await page.getByLabel('Email').fill('test@example.com');

  // 3. パスワードを入力
  await page.getByLabel('Password').fill('password123');

  // 4. ログインボタンをクリック
  await page
    .getByRole('button', { name: 'Sign in' })
    .click();

  // 5. ログイン成功の確認
  await expect(
    page.getByText('Welcome back')
  ).toBeVisible();
});

3. 生成されたコードを確認・編集する

生成されたコードを確認し、必要に応じて編集します:

javascript// 生成されたコードを改善する例
const { test, expect } = require('@playwright/test');

test('ログインフロー - 改善版', async ({ page }) => {
  // テストデータを変数として定義
  const testUser = {
    email: 'test@example.com',
    password: 'password123',
  };

  await page.goto('https://example.com/login');

  // より堅牢なセレクターを使用
  await page
    .getByTestId('email-input')
    .fill(testUser.email);
  await page
    .getByTestId('password-input')
    .fill(testUser.password);

  await page.getByTestId('login-button').click();

  // 複数のアサーションを追加
  await expect(
    page.getByText('Welcome back')
  ).toBeVisible();
  await expect(page).toHaveURL(/.*dashboard/);
  await expect(page.getByTestId('user-menu')).toBeVisible();
});

4. テストを実行する

作成したテストを実行して、正常に動作することを確認します:

bash# テストを実行
npx playwright test

# 特定のテストファイルを実行
npx playwright test login.spec.js

# ヘッドレスモードで実行
npx playwright test --headed

高度な機能と活用テクニック

基本的な使い方をマスターしたら、より高度な機能を活用してみましょう。

アサーションの追加

Recorder で生成されたコードに、より詳細なアサーションを追加します:

javascript// 基本的なアサーション
const { test, expect } = require('@playwright/test');

test('詳細なアサーション', async ({ page }) => {
  await page.goto('https://example.com/product/123');

  // 要素の存在確認
  await expect(
    page.getByText('Product Title')
  ).toBeVisible();

  // 要素の属性確認
  await expect(page.getByRole('img')).toHaveAttribute(
    'alt',
    'Product Image'
  );

  // 要素の状態確認
  await expect(
    page.getByRole('button', { name: 'Add to Cart' })
  ).toBeEnabled();

  // ページのURL確認
  await expect(page).toHaveURL(/.*product\/123/);

  // 要素のテキスト内容確認
  await expect(page.getByTestId('price')).toContainText(
    '$99.99'
  );
});

セレクターの最適化

生成されたセレクターを、より堅牢で保守しやすいものに最適化します:

javascript// セレクターの最適化例
const { test, expect } = require('@playwright/test');

test('最適化されたセレクター', async ({ page }) => {
  await page.goto('https://example.com');

  // 悪い例: テキストに依存したセレクター
  // await page.getByText('Login').click();

  // 良い例: テスト用のIDを使用
  await page.getByTestId('login-link').click();

  // 悪い例: クラス名に依存したセレクター
  // await page.locator('.btn-primary').click();

  // 良い例: 意味のあるロールと名前を使用
  await page
    .getByRole('button', { name: 'Submit' })
    .click();

  // 悪い例: 複雑なCSSセレクター
  // await page.locator('div.container > form > input[type="email"]').fill('test@example.com');

  // 良い例: シンプルで明確なセレクター
  await page.getByLabel('Email').fill('test@example.com');
});

テストケースの分割

大きなテストシナリオを、小さく管理しやすいテストケースに分割します:

javascript// テストケースの分割例
const { test, expect } = require('@playwright/test');

// ログインテスト
test('ユーザーログイン', async ({ page }) => {
  await page.goto('https://example.com/login');
  await page.getByLabel('Email').fill('test@example.com');
  await page.getByLabel('Password').fill('password123');
  await page
    .getByRole('button', { name: 'Sign in' })
    .click();
  await expect(
    page.getByText('Welcome back')
  ).toBeVisible();
});

// 商品検索テスト
test('商品検索機能', async ({ page }) => {
  await page.goto('https://example.com');
  await page
    .getByPlaceholder('Search products')
    .fill('laptop');
  await page
    .getByRole('button', { name: 'Search' })
    .click();
  await expect(
    page.getByText('Search results for "laptop"')
  ).toBeVisible();
});

// カート追加テスト
test('商品をカートに追加', async ({ page }) => {
  await page.goto('https://example.com/product/123');
  await page
    .getByRole('button', { name: 'Add to Cart' })
    .click();
  await expect(
    page.getByText('Item added to cart')
  ).toBeVisible();
});

よくある問題と解決方法

Recorder 機能を使用する際に、よく遭遇する問題とその解決方法を紹介します。

問題 1: セレクターが不安定

症状: テストが時々失敗する、要素が見つからない

javascript// 問題のあるコード
await page.getByText('Login').click(); // テキストが変更されると失敗

// 解決方法
await page.getByTestId('login-button').click(); // テスト用IDを使用

解決策: テスト用の属性(data-testid)を HTML に追加する

html<!-- HTMLの例 -->
<button data-testid="login-button" class="btn btn-primary">
  Login
</button>

問題 2: 動的コンテンツの待機

症状: ページの読み込みが完了する前に操作を実行してしまう

javascript// 問題のあるコード
await page.goto('https://example.com');
await page.getByRole('button', { name: 'Submit' }).click(); // 要素がまだ読み込まれていない可能性

// 解決方法
await page.goto('https://example.com');
await page.waitForLoadState('networkidle'); // ネットワークが安定するまで待機
await page.getByRole('button', { name: 'Submit' }).click();

問題 3: フレームやポップアップの処理

症状: iframe 内の要素やポップアップウィンドウの要素にアクセスできない

javascript// iframe内の要素にアクセス
const frame = page.frameLocator('iframe[name="content"]');
await frame.getByRole('button', { name: 'Submit' }).click();

// ポップアップウィンドウの処理
const [popup] = await Promise.all([
  page.waitForEvent('popup'),
  page.getByRole('button', { name: 'Open Popup' }).click(),
]);
await popup.getByText('Popup Content').click();

問題 4: 非同期処理の待機

症状: AJAX リクエストの完了を待たずにアサーションを実行する

javascript// 問題のあるコード
await page
  .getByRole('button', { name: 'Load Data' })
  .click();
await expect(page.getByText('Data loaded')).toBeVisible(); // データがまだ読み込まれていない可能性

// 解決方法
await page
  .getByRole('button', { name: 'Load Data' })
  .click();
await page.waitForResponse((response) =>
  response.url().includes('/api/data')
); // APIレスポンスを待機
await expect(page.getByText('Data loaded')).toBeVisible();

問題 5: モバイルレスポンシブ対応

症状: デスクトップでは動作するが、モバイルで失敗する

javascript// モバイルビューポートでのテスト
const { test, expect } = require('@playwright/test');

test('モバイルでのテスト', async ({ page }) => {
  // モバイルビューポートを設定
  await page.setViewportSize({ width: 375, height: 667 });

  await page.goto('https://example.com');

  // モバイルメニューの操作
  await page.getByRole('button', { name: 'Menu' }).click();
  await expect(page.getByText('Mobile Menu')).toBeVisible();
});

まとめ

Playwright の Recorder 機能は、テスト自動化の世界に革命をもたらす素晴らしいツールです。従来の手動コーディングから解放され、ブラウザでの操作だけでテストコードが生成されるという驚きの体験を提供してくれます。

この機能の最大の魅力は、学習コストの大幅な削減開発効率の向上です。初心者でも数分でテストを作成でき、経験者にとっては定型作業の自動化により、より創造的な作業に集中できるようになります。

また、生成されたコードは人間が理解しやすく、保守性も高いという特徴があります。必要に応じて手動で調整することも可能で、柔軟性と使いやすさを両立しています。

Recorder 機能を活用することで、あなたのテスト自動化の取り組みは、より楽しく、より効率的なものになるでしょう。今までテスト作成に時間を取られていた方も、この機能を使えば、本来の開発作業により多くの時間を割くことができるようになります。

テスト自動化は、もはや難しい技術ではありません。Playwright Recorder が、あなたのテスト作成を劇的に変えてくれることでしょう。

関連リンク