日本品質のテストエビデンス(画面キャプチャ・ログ)を自動生成するPlaywright自動化スクリプト完全解説
はじめに
こんにちは、NKKTech Global 技術チームです。
日本のシステム開発において、納品・検収条件として厳格に求められるのが「テストエビデンス」です。
- 「各入力ステップの前後でキャプチャを撮ること」
- 「操作したボタンや入力欄がどこか赤枠で明示されていること」
- 「実行日時、URL、通信エラーログが紐付いていること」
これらを手作業で行うと、テスト実行時間の70%以上が「キャプチャの切り貼り作業」に消えてしまいます。本記事では、Playwrightのライフサイクルフックとカスタムラッパーを用い、テストコードを書くだけで日本品質のエビデンス一式を自動出力する実装手法を完全解説します。
1. 「日本品質エビデンス」の自動化要件
SIerやエンタープライズの品質基準を満たすため、以下の要件を自動化スクリプトに組み込みます。
-
ステップ別ナンバリング保存:
01_ログイン画面表示_20261006_100000.pngのような追跡可能な命名規則。 - 操作箇所のハイライト表示: クリックや入力を行う対象要素に一時的な「赤枠(Red Border)」を付与してから撮影。
- 通信ログ・コンソールログの同時収集: キャプチャに対応するAPIリクエスト/レスポンスおよびコンソール警告をテキストログとして保存。
- マークダウン形式のエビデンスサマリ出力: 顧客へそのまま提出できる実行一覧レポートの自動生成。
2. ディレクトリ構成
tests/
├─ fixtures/
│ └─ evidence-fixture.ts # エビデンス収集カスタムフィクスチャ
├─ specs/
│ └─ user-registration.spec.ts # テストシナリオ
evidence/ # 自動出力される成果物フォルダ
└─ 2026-10-06_user-registration/
├─ 01_トップページ表示.png
├─ 02_メールアドレス入力.png
├─ 03_登録ボタン押下.png
├─ network.log
└─ evidence_report.md
3. 完全実装:カスタムフィクスチャ (evidence-fixture.ts)
Playwrightの標準 test を拡張し、ステップ実行と同時に「ハイライト+撮影+ログ記録」を行うヘルパークラスを定義します。
import { test as base, Page, Locator } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
export class EvidenceCollector {
private stepCount = 0;
private evidenceDir: string;
private logs: string[] = [];
constructor(private page: Page, testTitle: string) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
const sanitizedTitle = testTitle.replace(/[^a-zA-Z0-9_\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]/g, '_');
this.evidenceDir = path.join(process.cwd(), 'evidence', `${timestamp}_${sanitizedTitle}`);
if (!fs.existsSync(this.evidenceDir)) {
fs.mkdirSync(this.evidenceDir, { recursive: true });
}
// ネットワークエラーとコンソールログの収集
this.page.on('console', msg => this.logs.push(`[CONSOLE ${msg.type()}] ${msg.text()}`));
this.page.on('response', resp => {
if (resp.status() >= 400) {
this.logs.push(`[HTTP ${resp.status()}] ${resp.url()}`);
}
});
}
/**
* 操作対象を赤枠で囲み、エビデンスキャプチャを取得
*/
async takeStep(stepDescription: string, targetLocator?: Locator): Promise<void> {
this.stepCount++;
const stepNum = String(this.stepCount).padStart(2, '0');
const fileName = `${stepNum}_${stepDescription}.png`;
const filePath = path.join(this.evidenceDir, fileName);
// 操作対象の要素があれば赤枠を付与
if (targetLocator) {
await targetLocator.evaluate(el => {
el.style.outline = '3px solid red';
el.style.outlineOffset = '2px';
}).catch(() => {});
}
// スクリーンショット撮影(フルページ)
await this.page.screenshot({ path: filePath, fullPage: true });
// スタイルを元に戻す
if (targetLocator) {
await targetLocator.evaluate(el => {
el.style.outline = '';
el.style.outlineOffset = '';
}).catch(() => {});
}
this.logs.push(`[STEP ${stepNum}] ${stepDescription} (Screenshot: ${fileName})`);
}
/**
* テスト終了時にサマリレポートを出力
*/
async finalizeReport(testStatus: string): Promise<void> {
const reportPath = path.join(this.evidenceDir, 'evidence_report.md');
const logPath = path.join(this.evidenceDir, 'execution.log');
fs.writeFileSync(logPath, this.logs.join('\n'), 'utf-8');
const reportContent = `
# テスト実施エビデンス報告書
- **実施日時:** ${new Date().toLocaleString('ja-JP')}
- **合否判定:** **${testStatus.toUpperCase()}**
- **取得ステップ数:** ${this.stepCount}
## 実施ステップ一覧
${Array.from({ length: this.stepCount }, (_, i) => {
const num = String(i + 1).padStart(2, '0');
return `### Step ${num}\n`;
}).join('\n\n')}
`;
fs.writeFileSync(reportPath, reportContent.trim(), 'utf-8');
}
}
// Playwrightのテストランナーへフィクスチャを注入
export const test = base.extend<{ evidence: EvidenceCollector }>({
evidence: async ({ page }, use, testInfo) => {
const collector = new EvidenceCollector(page, testInfo.title);
await use(collector);
await collector.finalizeReport(testInfo.status ?? 'unknown');
},
});
export { expect } from '@playwright/test';
4. テストコードの実装 (user-registration.spec.ts)
カスタムフィクスチャを使用したテストの記述例です。通常の操作コードに1行加えるだけで、要素の赤枠強調とキャプチャが自動実行されます。
import { test, expect } from '../fixtures/evidence-fixture';
test('新規会員登録フローのエビデンス収集', async ({ page, evidence }) => {
// Step 1: 会員登録ページへの遷移
await page.goto('https://example.com/signup');
await evidence.takeStep('登録画面表示');
// Step 2: メールアドレスの入力(入力欄を赤枠強調して撮影)
const emailInput = page.locator('#email');
await emailInput.fill('qa-test@nkktech.com');
await evidence.takeStep('メールアドレス入力完了', emailInput);
// Step 3: 利用規約チェックボックスの選択
const termsCheckbox = page.locator('#agree-terms');
await termsCheckbox.check();
await evidence.takeStep('利用規約同意チェック', termsCheckbox);
// Step 4: 登録送信ボタンの押下前確認
const submitButton = page.locator('button[type="submit"]');
await evidence.takeStep('登録ボタン押下直前', submitButton);
await submitButton.click();
// Step 5: 完了画面の検証
await expect(page.locator('.success-message')).toBeVisible();
await evidence.takeStep('登録完了メッセージ表示');
});
5. CI/CDパイプラインとの連携(GitHub Actions)
GitHub Actions上で実行し、生成されたエビデンスフォルダ一式をZIPアーティファクトとして自動アップロードします。
name: E2E Automated Evidence Pipeline
on:
push:
branches: [ main, release/* ]
jobs:
test-and-evidence:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium
- name: Run E2E Tests with Evidence
run: npx playwright test
# エビデンスフォルダを成果物として保存(監査・検収用)
- name: Upload Test Evidence Artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-evidence-${{ github.run_id }}
path: evidence/
retention-days: 90
6. 得られるビジネス・品質面の効果
-
エビデンス作成工数の95%削減:
手作業によるキャプチャ取得・貼り付け・トリミング作業が完全に消失します。 -
ヒューマンエラーの根絶:
撮り忘れや、古いキャッシュ画面のキャプチャ混入といった検収差し戻しリスクをゼロにします。 -
リグレッションテストの容易化:
UI変更があった際も、スクリプトを再実行するだけで全画面のエビデンスが即座に最新化されます。
まとめ
「手動でエビデンスを撮る作業」は、エンジニアリングの本来の価値ではありません。Playwrightを活用して**「日本品質の厳格なエビデンス基準を満たしつつ、作業を完全自動化する」**ことこそが、アジャイルのスピードとSIの品質保証を両立させる現実解です。
NKKTech Globalでは、日本の商習慣や検収基準に精通したグローバルエンジニアリング体制を通じて、自動E2Eテスト環境の構築から運用自動化まで一貫して支援しています。
お問い合わせ先
E2Eテスト自動化の導入、QAプロセスの効率化、日本品質に準拠したオフショア開発体制の構築に関するご相談は、下記よりお気軽にお問い合わせください。
- Webサイト: https://nkktech.com/
- メール: contact@nkk.com.vn
- LinkedIn: https://www.linkedin.com/company/nkktech
