test-data-management について
テストエンジニア向けのテストデータ管理スキルで、ファクトリー、フィクスチャ、シード、クリーンアップ、匿名化を扱います。各テストが独自のデータを持つことで、再現性、並列実行、プライバシー保護を支援します。
主な機能
- 01上書き可能なデータをファクトリーで生成
- 02レスポンスや比較用ファイルにフィクスチャを使用
- 03冪等なデータベースシードを作成
- 04本番データの個人情報を匿名化
- 05テストデータを分離して後処理
- 06境界値や例外値の合成データを生成
活用シーン
- 01テストごとに独立したエンティティを作成
- 02API モックや参照データを準備
- 03非本番環境で匿名化データを使用
- 04テストを並列実行してデータをクリーンアップ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill test-data-managementインストール後、Claude Code で/test-data-managementを入力して読み込まれたか確認します。
同梱ファイルreferences/factories.mdreferences/seeding-and-synthetic.md
詳細
クイックガイド
| 状況 | 移動先 |
|---|---|
| テストごとに値を上書きして、新しいエンティティデータが必要 | ファクトリーパターン → references/factories.md |
| API レスポンスまたはゴールデンファイルをモックする | フィクスチャ戦略 → references/factories.md |
| 本番データを本番以外の環境にコピーする | データの匿名化 |
| テスト DB/参照データを冪等に投入する | データベースのシード → references/seeding-and-synthetic.md |
| テスト後のクリーンアップ/並列実行時の分離 | クリーンアップ戦略 → references/seeding-and-synthetic.md |
| エッジケースと境界値を生成する | 合成データ → references/seeding-and-synthetic.md |
確認事項
テストデータ戦略を設計する前に、現状を把握してください。まず .agents/qa-project-context.md を確認し、存在する場合はその内容を基盤として、すでに回答されている質問は省略してください。
現在のデータ運用
- 現在、テストデータはどのように作成されていますか?(手動、スクリプト、本番データのコピー、作成なし)
- テスト間でデータを共有していますか?それとも各テストが独自に作成していますか?
- テストデータはどのようにクリーンアップしていますか?(truncate、ロールバック、手動、クリーンアップなし)
- シードスクリプトはありますか?冪等ですか?
プライバシーとコンプライアンス
- 製品は PII を扱いますか?(名前、メールアドレス、住所、電話番号、SSN)
- GDPR、HIPAA、PCI-DSS、またはその他のデータ保護要件がありますか?
- テスト環境で本番データを使用することはありますか?
規模と複雑さ
- テストデータセットの規模はどの程度ですか?(数十件、数千件、数百万件)
- データの関連性はどの程度複雑ですか?(単純な CRUD、深い入れ子の階層、ポリモーフィック)
- サービス間でデータの依存関係はありますか?(データを共有するマイクロサービス)
基本原則
1. 各テストが自分のデータを所有する
既存の共有データに依存するテストは壊れやすくなります。テスト A が共有データを変更すると、テスト B が失敗します。各テストは必要なデータを正確に作成し、そのデータを使って検証し、自分でクリーンアップする必要があります。これにより並列実行が可能になり、実行順序への依存がなくなります。
2. 動的データにはフィクスチャよりファクトリーを使う
静的フィクスチャ(JSON/YAML ファイル)は、変化しない参照データ(国コード、通貨一覧)に適しています。テストで作成・操作するエンティティデータ(ユーザー、注文、製品)には、適切なデフォルト値を使って新しいインスタンスを生成し、テストごとに値を上書きできるファクトリー関数を使用してください。
3. 本番データは使用前に匿名化する
本番データベースには最も現実的なデータが含まれていますが、実際のユーザー情報も含まれています。匿名化せずに本番データをテスト環境にコピーすることは絶対に避けてください。データの分布と関連性を保ちながら、PII を合成データに置き換えてください。
4. 決定論的なデータで再現可能なテストを実現する
テストは、いつ、どこで実行しても同じ結果になる必要があります。アサーションでは Math.random()、Date.now()、自動採番 ID を避けてください。シード付き乱数生成器(faker.seed(n))、固定タイムスタンプ、ファクトリーのシーケンスを使い、アサーション対象の ID に UUID が必要な場合は、実行ごとに変わらないようシード付きの faker.string.uuid() を使用してください。
5. データは最小限に、テストの意図は明確に
各テストに必要なデータだけを作成してください。ユーザー検索のテストに、請求先住所、支払い方法、注文履歴を含む完全なユーザープロフィールは必要ありません。テストデータを過剰に指定すると、テストの意図が見えにくくなり、保守の負担も増えます。
ファクトリーパターン
ファクトリは、妥当なデフォルト値を持つテストデータを生成する関数です。これにより、各テストではシナリオに関係する項目だけを上書きできます。TypeScript では Fishery(2.4.0)、Ruby では FactoryBot(6.6.0)、Python では factory-boy(3.3.3)がデフォルトで、それぞれ現実的なフィールド値を生成する faker(v10.4.0)と組み合わせて使います。
Fishery(関連付けと決定論的な UUID を含む)、FactoryBot(User と Product の out_of_stock/discounted トレイト)、Factory Boy(class Params と Trait)、Playwright フィクスチャの実装については、references/factories.md を参照してください。すべてのファクトリに共通する構成は次のとおりです。
- デフォルト値+上書き —
Factory.defineで妥当なデフォルト値を生成し、テストでは必要なフィールドだけを上書きします(userFactory.build({ role: 'admin' }))。 - 一意なフィールドにはシーケンスを使用 —
sequence(Fishery)、sequence(:email)(FactoryBot)、factory.Sequence(Factory Boy)を使用し、ID やメールアドレスをハードコードしないでください。 - バリエーションにはトレイトを使用 — 組み合わせごとにフィクスチャファイルを作成するのではなく、よく使う状態に名前(
:admin、:inactive、out_of_stock、discounted)を付けます。 - 関連付け — あるファクトリから別のファクトリを生成します(注文からユーザーを生成するなど)。手動で関連付けを設定せずに、参照関係を維持できます。
ファクトリとフィクスチャの使い分け
| シナリオ | ファクトリ | 静的フィクスチャ |
|---|---|---|
| テストで作成/変更するエンティティデータ | はい | いいえ |
| 参照データ(国、通貨、設定) | いいえ | はい |
| テストごとに多くのバリエーションがあるデータ | はい | いいえ -- ファイルが増えすぎます |
| 複雑な関係を持つデータ | はい -- 関連付け | いいえ -- 保守が困難です |
| API レスポンスのモック | いいえ | はい -- JSON フィクスチャ |
| スナップショット/ゴールデンファイルの比較 | いいえ | はい |
判断基準: テスト中に作成、変更、削除されるライフサイクルを持つデータにはファクトリを使います。読み取り専用の参照データにはフィクスチャファイルを使います。
フィクスチャの戦略
references/factories.md では、次の 3 種類のフィクスチャをすべて扱います。
- 静的フィクスチャ(JSON/YAML) — API レスポンスのモック(
page.routeとroute.fulfill)、設定データ、ゴールデンファイルの比較に最適です。 - 動的フィクスチャ(Playwright) —
test.extendでテスト前に API 経由でデータを作成し、await use(...)の後に削除します。テストごとの標準的なセットアップ/ティアダウンです。 - フィクスチャの合成 — ファクトリで生成したデータ(
userFactory.build()、orderFactory.buildList(3))を、データの投入とクリーンアップを 1 回で行う単一のtest.extend内で組み合わせます。
データの匿名化
現実的なテストに本番データが必要な場合は、使用前に匿名化してください。
PII のマスキングルール
| データの種類 | 匿名化方法 | 例 |
|---|---|---|
| メールアドレス | 元のドメインパターンを維持した Faker のメールアドレス | [email protected] -> [email protected] |
| 氏名 | Faker の名前 | Jane Doe -> Alice Johnson |
| 電話番号 | 形式を維持した Faker の電話番号 | +1-555-123-4567 -> +1-555-987-6543 |
| 住所 | 国/地域を維持した Faker の住所 | 123 Main St, NYC -> 456 Oak Ave, NYC |
| SSN/国民 ID | テスト用パターン | 123-45-6789 -> 000-00-0001 |
| クレジットカード | テスト用カード番号 | 4111-... -> 4242-4242-4242-4242 |
| 生年月日 | 固定の期間ずらす | 1990-03-15 -> 1987-07-22 |
決定性のためのシード付き Faker、メモリ内ルックアップテーブル、親レコードを先に処理する順序、トランザクションによるラップを含む匿名化パイプラインについては、references/seeding-and-synthetic.md(Faker.js による匿名化、匿名化中の参照整合性)を参照してください。ユーザーのメールアドレスを匿名化する場合は、参照されているすべての場所(注文、コメント、監査ログなど)のメールアドレスも更新する必要があります。同じルックアップを使い、1 つのトランザクション内で親を先に、子を後に処理してください。
GDPR コンプライアンスチェックリスト
- 本番以外の環境に、実在する個人識別情報(PII)が存在しない
- 匿名化は不可逆である(元のデータに戻すための対応表を保存しない)
- 匿名化によってデータ分布(年齢層、地理的な広がり)が維持され、現実的なテストが可能である
- 準識別子の組み合わせによって、匿名化されたデータから個人を再識別できない
- テスト環境にもデータ保持ポリシーが適用される(N 日後に自動削除)
- 匿名化パイプラインが手動ではなく自動で実行される(人的ミスを排除)
データベースのシーディング
冪等なシードスクリプト
シードスクリプトは、複数回実行してもデータが重複しないようにします。主キーではなく、安定したナチュラルキーを基準に upsert(INSERT ... ON CONFLICT (natural_key) DO UPDATE SET ...)を使用します。DELETE の後に INSERT する「リセット」は冪等ではありません。外部キーを壊し、シリアル ID を再割り当てするためです。完全な INSERT ... ON CONFLICT (code) DO UPDATE の国/通貨の例とその理由については、references/seeding-and-synthetic.md(冪等なシードスクリプト)を参照してください。
データベースのブランチ作成(DB-as-a-Service)
本番データベースが Neon、Supabase、または PlanetScale 上にある場合、ブランチを作成すれば、ゼロからシードする代わりに PR 専用のデータベースを用意できます。ただし、ブランチにデータが引き継がれるかどうかはプロバイダーによって異なります。
- Neon Branching — データを含む Postgres ブランチを数秒でコピーオンライト方式で作成でき、一時的なプレビュー環境に最適です。「PR ごとに実際の DB コピーを用意する」という点では最も優れています。
- Supabase Branching —
supabase branches create pr-123でスキーマと(必要に応じてバックアップから)データを複製します。プレビュー環境はブランチの URL を参照します。 - PlanetScale Branching — MySQL のブランチには、デフォルトでスキーマのみが含まれ(データは含まれません)、そのためブランチにシードする必要があります。注:PlanetScale は無料の Hobby プランを終了しました(2024 年 4 月)。MySQL は現在約 $39/月、Postgres は約 $5/月から利用できます。
test-environments のプレビュー環境パターンと組み合わせてください。
避ける:Snaplet(ホステッド) — 2024 年 8 月 31 日にサービスを終了し、チームは Supabase に加わりました。
@snaplet/seedはsupabase-community/seedとして存続しています(コミュニティが保守。意味のある最後のリリースは v0.98.0、 2024 年 7 月で、それ以降機能開発はありません)。新規プロジェクトでは、上記の DB ブランチ作成プロバイダーと ファクトリー生成シードの組み合わせを推奨します。
テスト単位とテストスイート単位のデータ
| 戦略 | 使用する場面 | メリット | デメリット |
|---|---|---|---|
| テストごとのセットアップ/後処理 | データを変更するテスト | 完全な分離、並列実行に安全 | 遅く、セットアップコードが増える |
| テストスイートごとのシード | 読み取り専用の参照データ | 高速、シンプル | テストから変更できない |
| ワーカーごとのシード | Playwright の並列ワーカー | 速度と分離のバランスが取れる | ワーカー単位のフィクスチャが必要 |
| グローバルシード | 環境のブートストラップ | 1 回だけ実行され、ベースラインを設定 | 冪等である必要があり、共有状態のリスクがある |
ワーカーごとのシーディングに使用するワーカー単位のフィクスチャ({ scope: 'worker' } を指定した test.extend)については、references/factories.md(ワーカー単位のシーディング)を参照してください。
クリーンアップ戦略
| 戦略 | 使用する場面 | 速度 |
|---|---|---|
| トランザクションのロールバック | DB に直接アクセスする単体/統合テスト | 最速 |
トランケーション(TRUNCATE ... CASCADE) | テストスイート間でのテーブルのリセット | 中程度 |
| API ベースのクリーンアップ | DB に直接アクセスしない E2E テスト | 最遅 |
トランザクションのロールバックでは E2E テストをクリーンアップできません。アプリが独自の DB 接続を開くため、テスト側のトランザクションではアプリによる書き込みを取り消せません。その場合は API ベースのクリーンアップ(作成と逆の順序で削除)を使用してください。3 つの実装すべてについては、references/seeding-and-synthetic.md(クリーンアップ戦略)を参照してください。
合成データの生成
ファクトリーを使えば、テストごとに手書きしなくても、エッジケースや境界値を簡単に生成できます。test.each を使ってテストを実行する再利用可能な配列とヘルパー、すなわち edgeCaseStrings(空文字、空白、非常に長い文字列、XSS、SQL インジェクション、null/制御文字、RTL オーバーライド)、edgeCaseDates、boundaryValues(min, max) は、references/seeding-and-synthetic.md(合成データの生成)にあります。
アンチパターン
共有された可変テストデータ
複数のテストが同じデータベースの行を読み書きすることです。テスト A がユーザーを作成し、テスト B がそれを変更し、テスト C が元の状態を検証して失敗します。各テストがファクトリーを使って独自のデータを作成するようにしてください。
匿名化されていない本番データ
「現実的なテスト」のために本番データベースをステージング環境にコピーすることです。これは GDPR に違反し、セキュリティの低い環境でデータ漏えいのリスクを高め、コンプライアンス上の責任を生じさせます。使用前に必ず匿名化するか、本番環境の分布に合った合成データを生成してください。
非決定的なデータ
シードを設定せずに、テストデータの作成に Math.random() や Date.now() を使用することです。ランダムに生成された名前がフィールドの長さ制限を超えると、月曜日には成功したテストが火曜日には失敗します。シードを設定した Faker インスタンスと固定タイムスタンプを使用してください。
クリーンアップ戦略がない
データを作成しても、クリーンアップしないテストです。テストデータベースがパフォーマンスに影響するほど肥大化したり、古いデータによって他のテストで誤検知が発生したりします。データを作成するたびに、対応するクリーンアップを行ってください。
フィクスチャファイルの乱立
テストのバリエーションごとに別個の JSON フィクスチャファイルを作成することです。user-admin.json、user-inactive.json、user-admin-inactive.json の代わりに、トレイト付きのファクトリーを使用してください。フィクスチャは、静的な参照データと API レスポンスのモックに限って使用してください。
過剰に指定されたテストデータ
テストで role しか確認しないのに、30 個のフィールドを持つ完全なユーザーオブジェクトを作成することです。意図が分かりにくくなり、テストが壊れやすくなります。妥当なデフォルト値を備えたファクトリーを使えば、テストで必要な値だけを上書きできます。
ハードコードされた ID
テストで userId: '1' を使用することです。これによりテストがデータベースの状態に依存し、並列実行時(ID の衝突)や既存データのあるデータベースで失敗します。ファクトリーのシーケンスまたはシード付き UUID を使用してください(コア原則 4 を参照)。
検証
データレイヤーが決定論的で、分離され、PII を含まないことを、小さなチェックから順に確認します。
- シードは冪等です — シードを連続して 2 回実行し、行数を比較します。
psql -c "SELECT count(*) FROM countries" && <seed> && psql -c "SELECT count(*) FROM countries"は、どちらの実行後も同じ数を返し、終了コード 0 で終了します。行数が増える場合は、ON CONFLICTが不足しています。 - 共有された可変状態がありません — 並列実行とランダムな順序の両方でテストスイートを実行します。
npx playwright test --workers=4(またはpytest -n auto -p randomly)が成功し続けます。この場合にのみ発生する失敗は、実行順序または共有データへの依存を示しています。 - 決定性が保たれています — データを生成する同じテストを 2 回実行します。
faker.seed(n)を設定すると、生成される名前/ID/UUID は実行間で一致します。結果が変わる場合は、シードのない Faker 呼び出し、またはDate.now()/crypto.randomUUID()が混入しています。 - 実際の PII がありません —
grep -rE '@(gmail|outlook|yahoo)\.com|[0-9]{3}-[0-9]{2}-[0-9]{4}' tests/ fixtures/が何も返さないことを確認します(実在しそうなメールアドレスと SSN が対象です)。該当するものがあれば、匿名化が不十分です。 - クリーンアップ後にベースラインに戻ります — テストスイートの実行前に行数を記録し、実行後にもう一度記録します。テストデータベースがベースラインに戻り、孤立したレコードがないことを確認します。
完了の基準
- スイートが作成するすべてのエンティティ型にファクトリーまたはフィクスチャがあります(共有エンティティをテスト内でその場しのぎのオブジェクトリテラルとして作成しません。テストディレクトリを grep で検索し、手作業で作成したフィクスチャが残っていないことを確認してください)。
- テストデータはテストごとに分離されています。並列実行(
--workers=N/pytest -n auto)およびランダムな順序(--shuffle/-p randomly)でスイートが成功し、共有された可変状態や実行順序への依存がないことを証明します。 - シードスクリプトは冪等です。シードを2回続けて実行しても行数が変わらず、終了コード0で終了します。CI ジョブでは、手動操作なしでスクリプトを実行します。
- テスト用フィクスチャに実際の PII は使いません。機密データはすべて匿名化または合成データにします(本番ドメインや実在しそうな SSN を grep で検索しても何も見つかりません)。
- データのクリーンアップを検証します。スイートの実行後、テスト DB の行数がベースラインに戻り、実行を重ねても孤立レコードが蓄積しません。
参考ファイル(references/ 内)
- factories.md — Fishery(関連付け、決定論的な UUID)、FactoryBot(User + Product トレイト)、Factory Boy(
Params/Trait)、静的/動的/合成 Playwright フィクスチャ、ワーカー単位のシーディングフィクスチャについて説明します。 - seeding-and-synthetic.md — 冪等な
ON CONFLICTシードスクリプト、Faker.js による匿名化と参照整合性のパイプライン、クリーンアップ戦略(ロールバック/トランケート/API)、合成エッジケースと境界値のジェネレーターについて説明します。
関連スキル
- unit-testing -- ユニットテストはファクトリー生成データの主な利用者です。このスキルではデータレイヤーを提供します。
- api-testing -- API テストでは、ファクトリー(リクエストボディ用)とフィクスチャ(モックレスポンス用)の両方を使用します。
- playwright-automation -- E2E テストでは、ブラウザー操作の前に API またはフィクスチャを使ってテストデータをシードする必要があります。
- test-reliability -- 決定論的なテストデータにより、テストが不安定になる主な原因を1つ取り除けます。
- test-environments -- プレビュー環境向けの環境プロビジョニングとデータベースブランチ戦略(Neon、Supabase、PlanetScale)を担当します。このスキルでは、それらの環境に投入するデータを担当します。
- database-testing -- データベースレイヤーに特化したマイグレーションテスト、データ整合性のアサーション、Testcontainers を扱います。DB のテストはこちらで行い、データの投入はこちらで行います。
- ci-cd-integration -- データベースのシーディングとクリーンアップは、CI パイプラインのステージに組み込む必要があります。