Playwrightにおけるフィクスチャについて

# フィクスチャとは

フィクスチャ（Fixture）とは、テストの実行に必要な前提条件や環境を整えるための仕組みや設定を指します。具体的には、テストを実行する前に必要なデータや状態を準備し、テストの実行をスムーズにするためのものです。以下にフィクスチャの主な特徴と役割を説明します。

### **フィクスチャの主な特徴**

**前提条件の設定**

- テストを実行するために必要な状態やデータを事前に準備します。これにより、テストが正しく実行されるための環境を整えます。

**再利用性**

- フィクスチャは、複数のテストで共通して使用できるため、同じ準備処理を繰り返す必要がなくなります。これにより、テストコードの重複を減らし、メンテナンスが容易になります。

**テストの可読性向上**

- フィクスチャを使用することで、テストコードがよりシンプルで読みやすくなります。テスト本体では、フィクスチャによって整えられた状態を前提にした処理を行うことができるため、テストの意図が明確になります。

**ライフサイクル管理**

- フィクスチャは、テストの実行前後に必要な処理を自動的に行うことができます。例えば、テストの前にデータベースを初期化したり、テスト後にクリーンアップを行ったりすることができます。

# PageObjectModelとフィクスチャの類似点と相違点

Page Object Model（POM）とフィクスチャは、テストコードの可読性や保守性を向上させるための手法ですが、それぞれの目的や存在意義には明確な違いがあります。以下に、両者の類似点と存在意義の違いを説明します。

## PageObjectModelとフィクスチャの類似点

**可読性の向上**

- 両者は、テストコードをよりシンプルで理解しやすくするために使用されます。Page Object はページの操作を抽象化し、フィクスチャはテストの前提条件を整えることで、テストの意図を明確にします。

**再利用性**

- Page Object とフィクスチャは、共通の処理や設定を再利用するための手段です。これにより、テストコードの重複を減らし、メンテナンスが容易になります。

**テストの効率化**

- 両者は、テストの実行を効率化する役割を果たします。Page Object はページ操作を簡素化し、フィクスチャはテストの準備を効率化します。

## PageObjectModelとフィクスチャの相違点

### **目的の違い**

**Page Object**

- 主にアプリケーションの UI 操作を抽象化し、ページごとの操作や要素をカプセル化することを目的としています。これにより、テストコードはページの詳細を意識せずに操作を行うことができます。

**フィクスチャ**

- テストの実行に必要な前提条件や環境を整えることを目的としています。フィクスチャは、テストが正しく実行されるための状態を準備し、テストの実行をスムーズにします。

### **スコープの違い**:

**Page Object**

- アプリケーションの特定のページやコンポーネントに関連する操作を管理します。各ページオブジェクトは、そのページに特有のメソッドやプロパティを持ち、ページの操作をカプセル化します。

**フィクスチャ**

- テスト全体に対する前処理や後処理を管理します。フィクスチャは、特定のテストケースやテストスイートに対して適用され、必要な状態を整える役割を果たします。

### **実行タイミングの違い**:

**Page Object**

- テストが実行される際に、必要な操作を呼び出すことで使用されます。テストの実行中にページオブジェクトのメソッドを呼び出して操作を行います。

**フィクスチャ**

- テストが実行される前に必要な処理を行います。フィクスチャは、テストの実行前に状態を整え、テスト本体ではその状態を前提にした処理を行います。

# 具体例

### test-options.tsの作成

例えば、test-options.tsとして以下の様に定義します。

```tsx
import { test as base } from '@playwright/test';
import { PageManager } from './page-objects/pageManager';

// フィクスチャとして他のテストで使用したいものの型を定義します。
export type TestOptions = {
  formLayoutsPage: string;
  pageManager: PageManager;
};

// フィクスチャを定義します。
export const test = base.extend<TestOptions>({
  // テスト前にフォームレイアウトページに移動します。
  formLayoutsPage: async ({ page }, use) => {
    await page.goto('/');
    await page.getByText('Forms').click();
    await page.getByText('Form Layouts').click();
    // await use('')までがテストの前処理。
    await use('');
    // await use('')以降がテストの後処理。
    console.log('TearDown');
  },

  // ページマネージャーを生成します。
  pageManager: async ({ page }, use) => {
    const pm = new PageManager(page);
    await use(pm);
  },
});
```

### testWithFixture.tsの作成

testWithFixture.tsの中でフィクスチャを使ってみます。

コメントアウトされた部分がフィクスチャによって省略できた部分です。

test-options.tsの中で作成したフィクスチャは

test('parametrized methods', async ({ page, formLayoutsPage, pageManager }) => {

部分でtest内に渡しています。

```tsx
import { faker } from '@faker-js/faker';
import { test } from '../test-options';

test('parametrized methods', async ({ page, formLayoutsPage, pageManager }) => {
  // const pm = new PageManager(page);
  const randomFullname = faker.person.fullName();
  const randomEmail = `${randomFullname.toLowerCase().replace(/\s+/g, '.')}${faker.number.int(1000)}@test.com`;

  // await pm.navigateTo().fromLayoutsPage();
  await pageManager.onFormLayoutsPage().submitUsingTheGridWithCredentialsAndSelectOption(process.env.USERNAME, process.env.PASSWORD, 'Option 1');
  await pageManager.onFormLayoutsPage().submitInlineFormWithNameEmailAndCheckbox(randomFullname, randomEmail, false);
});
```