この記事では、Playwrightを使用してネットワークリクエストをインターセプトし、モックデータを使ってテストを行う方法を解説する。この技術を活用することで、実際のAPIエンドポイントに依存せずに、安定したテストを実行できる。
ネットワークインターセプトとモックの重要性
ネットワークリクエストのインターセプトとモックは、実際のAPIが利用できない状況でもテストを実行できる。APIがダウンしている、APIの開発がまだ完了していない、あるいはエンドポイントがテスト時に変更される可能性がある場合などに活用できる。また、環境に依存したケース(開発では再現しないが、ステージングで再現した場合)などに、再現性のあるテストを実現し、テスト結果の信頼性を高めることができる。
Playwrightでのネットワークインターセプトの基本
Playwrightでは、page.route()
メソッドを使用してネットワークリクエストをインターセプトし、モックデータを返すことができる。この方法により、特定のリクエストに対してカスタマイズしたレスポンスを返すことで、テストのシナリオを自由に制御できる。
サンプルコード: 基本的なネットワークインターセプト
以下は、JSONPlaceholderのAPIリクエストをインターセプトし、モックデータを返す例だ。
まず、画面表示のコードを作成する。
pages/test/playwright/mock.vue
<template>
<v-container>
<h1 id="post-title">{{ post.title }}</h1>
<p id="post-body">{{ post.body }}</p>
</v-container>
</template>
<script setup>
import { ref, onMounted } from "vue";
const post = ref({
title: "",
body: "",
});
onMounted(async () => {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const data = await response.json();
post.value = data;
} catch (error) {
console.error("Failed to fetch post data:", error);
}
});
</script>
http://localhost:3000/test/playwright/mock
にアクセスすると、以下の表示となる。
この時点では、JSONPlaceholderのデータが表示される。
テストファイルにて、ネットワークリクエストをインターセプトし、モックデータを返すように変更する。
import { test, expect } from "@playwright/test";
test("Mock API response", async ({ page }) => {
// JSONPlaceholderへのリクエストをインターセプトし、モックデータを返す
await page.route("https://jsonplaceholder.typicode.com/posts/1", async (route) => {
const mockData = {
userId: 1,
id: 1,
title: "モックタイトル",
body: "モックデータの説明文が入ります。",
};
// モックレスポンスを返す
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(mockData),
});
});
// ページに移動
await page.goto("http://localhost:3000/test/playwright/mock");
// データが表示されるのを待つ
await page.waitForSelector("#post-title");
// ページ上での動作を検証
const title = await page.textContent("#post-title");
const body = await page.textContent("#post-body");
expect(title).toBe("モックタイトル");
expect(body).toBe("モックデータの説明文が入ります。");
});
実行すると、テストが成功しモックデータを表示できていることがわかる。
テストコードの解説
page.route()
: このメソッドを使用して、指定されたURLパターンに一致するリクエストをインターセプトする。ここでは、JSONPlaceholderの/posts/1
エンドポイントへのリクエストをモックしている。
route.fulfill()
: インターセプトされたリクエストに対してカスタムレスポンスを返すメソッド。モックデータをJSON形式で返すことで、実際のAPIレスポンスをシミュレートしている。
高度なネットワークインターセプトとモック
複数のリクエストをインターセプトしたり、条件に応じて異なるモックデータを返すことも可能。以下は、JSONPlaceholderの複数のAPIリクエストをインターセプトし、それぞれに異なるモックレスポンスを返す例。
import { test, expect } from "@playwright/test";
test("Mock API response", async ({ page }) => {
// posts/1のリクエストをモック
await page.route('https://jsonplaceholder.typicode.com/posts/1', async route => {
const postMock = {
userId: 1,
id: 1,
title: 'Mocked Post 1',
body: 'This is the first mocked post.'
};
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(postMock),
});
});
// posts/2のリクエストをモック
await page.route('https://jsonplaceholder.typicode.com/posts/2', async route => {
const postMock = {
userId: 1,
id: 2,
title: 'Mocked Post 2',
body: 'This is the second mocked post.'
};
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(postMock),
});
});
// ページに移動
await page.goto("http://localhost:3000/test/playwright/mock");
// データが表示されるのを待つ
await page.waitForSelector("#post-title-1");
await page.waitForSelector("#post-title-2");
// ページ上での動作を検証
const postTitle1 = await page.textContent("#post-title-1");
const postBody1 = await page.textContent("#post-body-1");
const postTitle2 = await page.textContent("#post-title-2");
const postBody2 = await page.textContent("#post-body-2");
expect(postTitle1).toBe('Mocked Post 1');
expect(postBody1).toBe('This is the first mocked post.');
expect(postTitle2).toBe('Mocked Post 2');
expect(postBody2).toBe('This is the second mocked post.');
});
まとめ
ネットワークリクエストのインターセプトとモックは、実際のプロジェクトでもかなり重宝する。特に、バックエンドの開発がまだ完了していない場合や、外部APIへの依存を排除したい場合に役立つ。また、エラーハンドリングのテストや、特定のシナリオで発生するレアケースの検証にも使用できるのでおすすめだ。
コメント