testing-in-production について
QAやエンジニアリングチーム向けに、本番環境でリリースを検証するスキルです。機能フラグ、段階的ロールアウト、スモークテスト、ロールバック検証を扱います。
主な機能
- 01機能フラグ状態のテスト
- 02段階的なトラフィック展開
- 03デプロイ後のスモークテスト
- 04ガードレールと自動ロールバック
- 05合成アカウントによる安全な検査
活用シーン
- 01機能をユーザーへ段階的に公開
- 02デプロイ後に重要経路を確認
- 03メトリクスに基づき停止やロールバック
- 04ロールバック後の復旧を検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill testing-in-productionインストール後、Claude Code で/testing-in-productionを入力して読み込まれたか確認します。
同梱ファイルreferences/patterns.mdreferences/rollout-policy.md
詳細
クイックルート
| 状況 | 移動先 |
|---|---|
| フラグを使って機能をリリースする | フィーチャーフラグのテスト |
| ゲートを設けてトラフィックを1%から100%へ段階的に増やす | 段階的なロールアウト + references/rollout-policy.md |
| リリースごとにデプロイ後のチェックが必要 | 本番環境のスモークテスト + references/patterns.md |
| ロールアウトのゲートに使う数値を決める | ガードレール指標 |
| ユーザーにまだ見える変化がない新しいコードパス | ダークローンチ |
| ロールバックが実際に機能することを証明する | 検証 |
発見のための質問
まず .agents/qa-project-context.md を確認してください。存在する場合は、その内容をコンテキストとして使い、すでに回答されている質問は省略してください。
フィーチャーフラグシステム:
- フィーチャーフラグプラットフォームはありますか?(LaunchDarkly、Statsig — 現在は OpenAI の一部、GrowthBook、Unleash、Flagsmith、Harness FME — 旧 Split、独自のもの、なし)
- フラグはどのように管理していますか?(ダッシュボード、設定ファイル、環境変数)
- 特定のユーザー、割合、セグメントを対象にフラグを設定できますか?
- 現在、有効なフラグはいくつありますか?クリーンアップのプロセスはありますか?
ロールアウト機能:
- トラフィックの一部に限定してデプロイできますか?(カナリアインフラストラクチャ、重み付けルーティング、フィーチャーフラグ)
- デプロイにはどれくらいかかりますか?ロールバックにはどれくらいかかりますか?
- ブルーグリーンデプロイやローリングデプロイを行っていますか?
- リージョン、ユーザーコホート、割合を指定してトラフィックをルーティングできますか?
モニタリングの成熟度:
- どのような可観測性の仕組みがありますか?(APM、ログ記録、エラートラッキング、メトリクス)
- エラー率、レイテンシ、ビジネス指標を確認するダッシュボードはありますか?
- 適切なしきい値でアラートが設定されていますか?
- カナリアとベースラインのメトリクスをリアルタイムで比較できますか?
本番環境へのアクセスと安全性:
- 本番環境へのアクセス権を持つのは誰ですか?承認プロセスはありますか?
- 本番環境に専用のテストアカウントはありますか?
- 実際のユーザーデータに影響を与えずに、本番環境で操作を実行できますか?
- 本番環境のインシデント対応プロセスはありますか?
基本原則
1. 本番環境は最終テスト環境です
ステージング環境は本番環境を近似するものです。本番環境のデータ量、トラフィックパターン、サードパーティとの連携、インフラストラクチャの特異な挙動、ユーザー行動を再現するものではありません。本番環境でのテストは無謀ではなく、現実的な方法です。問うべきなのは、本番環境でテストするかどうかではなく、どうすれば安全に実施できるかです。
2. 影響範囲の制御によって安全を確保する
本番環境でのテストではすべて、「問題が起きた場合、何人のユーザーに影響するか」に答える必要があります。その答えは、できる限り小さくなければなりません。フィーチャーフラグ、カナリアデプロイ、トラフィック分割を使えば、影響範囲を100%から1%以下に縮小できます。
3. 常に検証済みのロールバック計画を用意する
本番環境でテストを始める前に、ロールバックの仕組みを特定し、テストして、すばやく実行できるようにしておく必要があります。「フラグを無効にする」は適切なロールバック計画です。「前のバージョンを再デプロイする」も許容できます。「どうにかします」は計画ではありません。一度も実行したことのないロールバックは計画ではなく仮説です。機能することを証明する方法については、検証を参照してください。
4. モニタリングは前提条件であり、あれば望ましいというものではありません
モニタリングなしに本番環境でテストすることはできません。エラー率、レイテンシ、ビジネス指標をリアルタイムで測定できなければ、問題を検出できません。本番環境でのテストを追加する前に、モニタリングの不備を解消してください。
5. 本番テストでは破壊的な操作を行わない
本番テストでは、実際のユーザーデータを破損させたり、実際のユーザーに本物の通知を送信したり、実際の決済手段に課金したり、手動でのクリーンアップが必要な副作用を発生させたりしてはいけません。合成アカウント、テストフラグ、分離されたリソースは必須です。
フィーチャーフラグのテスト
フィーチャーフラグは、本番環境でテストを行うための最も安全な仕組みです。デプロイとリリースを切り離し、即座にロールバックできます。
フラグのONとOFFでテストする
フラグが設定されたすべての機能について、両方の状態でテストする必要があります。フラグがOFFの経路はロールバック経路であり、問題なく動作しなければなりません。setFeatureFlag(name, true|false, { userId: TEST_USER_ID })を使って、両方の状態をテストしてください。ON/OFFのテストペア全体については、references/patterns.mdを参照してください。
フラグのライフサイクルテスト
フラグは単にONかOFFかだけではありません。状態間を遷移するため、それぞれの遷移を検証する必要があります。
Flag lifecycle:
Created → Targeting internal users → Canary (1%) → Partial (10-50%) → Full (100%) → Cleanup (removed)
Test at each stage:
- Internal: Feature works for internal accounts, hidden from external
- Canary: Metrics are comparable between flag-on and flag-off cohorts
- Partial: No performance degradation at scale
- Full: All user segments work correctly
- Cleanup: Code with flag removed behaves identically to flag-on
古くなったフラグの整理
コードに残ったフラグは技術的負債になります。100%ロールアウト済みで、14日より前に作成されたフラグをフラグプロバイダーに問い合わせる週次CIジョブを実行してください。これらはコードを整理する候補です。フラグの分岐ロジックを削除し、有効化された経路だけを残してください。不要なコードを削除せずにフラグだけを削除しても、クリーンアップは半分しか完了していません。
フラグの組み合わせテスト
複数のフラグが相互に作用する場合、重要な組み合わせをテストしてください。2^N通りの組み合わせをすべてテストするのは避けてください。同じユーザーフローに影響するフラグに絞ります(例:new-checkout、express-pay、discount-engine-v2はいずれもチェックアウトに関係します)。重要な組み合わせとして、すべて新しい状態、代表的な混在状態、すべて従来の状態を選んでください。組み合わせテストのループについては、references/patterns.mdを参照してください。
段階的ロールアウト
ベンダー標準のカナリア分析。 以下のロールアウトポリシーYAMLを独自に実装する前に、利用中のプラットフォームに同様の機能がすでに備わっていないか確認してください。LaunchDarkly Guarded Rollouts(メトリクスに基づく自動ロールバック機能を備えた、自動監視付きの段階的ロールアウト。2026年初頭以降、頻度論的な逐次検定分析モデルを使用)、Statsig Auto-tune、Argo Rollouts AnalysisRun、Flagger、Harness Continuous Verificationなどがあります。利用できるものがある場合は、そちらを優先してください。メトリクスやロールバックの仕組みとの統合により、独自の分析ループを保守するよりもコストを抑えられます。
AI機能のロールアウトには、独自のパターンがあります。モデルのバリアントとプロンプトをフラグの値として設定し、コストのガードレールとキルスイッチを設けます。LLM機能を段階的ロールアウトでリリースするためのドキュメント化された方法は、LaunchDarkly AI Configs / AgentControlです(AI Configsは、2026年5月に発表されたAgentControlの傘下でブランド変更されました)。このパターン全体については、
release-readinessを参照してください。
カナリア段階:1%から100%まで
各段階に明確な昇格基準を設けた、体系的なロールアウトです。
| 段階 | トラフィック | 保持時間 | 主な確認項目 |
|---|---|---|---|
| カナリア | 1% | 15-30 min | エラー率、クラッシュ率、例外 |
| 早期導入者 | 10% | 1-2 hours | レイテンシP95、コンバージョン率 |
| 一部 | 50% | 2-4 hours | すべてのガードレール、ビジネスメトリクス |
| 全体 | 100% | 24 hours monitoring | ロングテールの問題、バッチジョブとの互換性 |
自動昇格とロールバック
段階を進めるための機械検証可能な条件を定義します。hold_durationに加え、メトリクス条件(error_rate_5xx < 0.5%、latency_p95 < 500ms、crash_rate == 0)を設定します。ガードレールに違反した場合は、人間の承認なしで自動ロールバックを実行します。error_rate_5xx > 2x_baseline for 5m、latency_p99 > 3x_baseline for 5m、crash_rate > 0.1% for 2mが発生した場合は、それぞれオンコール担当者に通知します。生の倍率だけでなく、エラーバジェットの消費率を基準とすることで、SLOに違反する緩やかな劣化も検出できます。昇格用YAML、ロールバックのトリガー、SLOゲートの設定全体については、references/rollout-policy.mdを参照してください。
ロールバックが正しく実行されたことを確認する
自動ロールバックが実行されたことと、インシデントが解決したことは同じではありません。ロールバックがトリガーされた後、システムが実際に復旧したことを確認するまでは、「復旧した」と宣言しないでください。
- 本番環境に対してヘルスチェックのスモークテストを再実行します(
GET /api/healthがhealthyと以前のversionを返すこと)。 - フラグ/デプロイの状態が元に戻ったことを確認します — フラグプラットフォームに問い合わせてフラグがオフになっていること(または、以前のビルドが稼働していること)を確認し、思い込みで判断しないでください。
- ガードレール指標がベースラインに戻ったことを確認します — エラー率、P99 レイテンシ、クラッシュ率が、デプロイ前の期間内の値に戻っていることを確認します。
- ロールバックの通知がオンコール担当者に届いたことを確認します(Slack/PagerDuty)。これにより、インシデントの担当者が明確になります。
4 つすべてが満たされた場合に限り、ロールバックが検証済みとなります。本番環境で初めて使用する前にこの一連の流れを実証するステージング環境でのドライランについては、検証を参照してください。
本番スモークテスト
デプロイ後のクリティカルパステスト
すべてのデプロイ直後にパイプラインのステージとして実行します(デプロイ前の CI だけで実行するのではありません)。本番環境の構成、データ、インフラで主要機能が動作することを検証します。対象には、/api/health のチェック、合成認証情報を使った認証フロー、コアデータの読み込み、検索が含まれます。デプロイ後のテストが一度の不安定な実行でパイプラインをブロックしないよう、retries: 1 と timeout を設定してください。完全な production-smoke.spec.ts については、references/patterns.md を参照してください。
合成ユーザーアカウント
本番テストアカウントは、実際のユーザーと明確に区別できるようにする必要があります。予約済みのメールパターン(smoke-test+{env}@yourcompany.com)、is_synthetic = true フラグを使用し、分析、課金、メールキャンペーンの対象から除外してください。アカウントは管理者 API を通じて作成し、長期間有効なパスワードよりも、有効期間の短い OIDC/ワークロード ID トークンを優先してください。規約の詳細については、references/patterns.md を参照してください。
非破壊的なアサーション
本番スモークテストでは、書き込みではなく読み取りを行ってください。書き込みが避けられない場合は、テストが成功しても失敗してもクリーンアップが実行されるよう、フィクスチャのティアダウンでクリーンアップしてください。
test() 本体の中で test.afterEach() を呼び出さないでください。Playwright はフックを describe/ファイルのスコープで登録するため、テスト実行中に登録されたフックはティアダウンをスケジュールせず、test.afterEach() can only be called in a describe block というエラーをスローします。データが残ってしまいます。作成したリソース ID を記録し、ティアダウン時に削除する自動クリーンアップフィクスチャを使用してください(単発のスクリプトの場合は try/finally を使用してください)。フィクスチャベースの作成・検証・クリーンアップのパターンについては、references/patterns.md を参照してください。
ガードレール指標
ロールアウト中に監視する項目
| カテゴリ | 指標 | 比較方法 | アラートしきい値 |
|---|---|---|---|
| エラー | HTTP 5xx 率 | デプロイ前のベースラインとの比較 | 5 分間、ベースラインの 2 倍超 |
| エラー | 未処理例外の数 | デプロイ前のベースラインとの比較 | 新しい例外タイプが 1 件でも発生 |
| レイテンシ | P50 応答時間 | デプロイ前のベースラインとの比較 | ベースラインの 1.5 倍超 |
| レイテンシ | P95 応答時間 | デプロイ前のベースラインとの比較 | ベースラインの 2 倍超 |
| レイテンシ | P99 応答時間 | デプロイ前のベースラインとの比較 | ベースラインの 3 倍超 |
| ビジネス | コンバージョン率 | 7 日間の平均との比較 | 5% 超の低下 |
| ビジネス | セッションあたりの収益 | 7 日間の平均との比較 | 10% 超の低下 |
| クライアント | クラッシュ率(モバイル) | 以前のリリースとの比較 | 0.1% 超の増加 |
| クライアント | JavaScript エラー率 | デプロイ前のベースラインとの比較 | ベースラインの 2 倍超 |
| インフラ | CPU 使用率 | 絶対値 | 80% 超が継続 |
| インフラ | メモリ使用率 | 絶対値 | 85% 超が継続 |
ベースラインとの比較
カナリアの指標は、過去のデータだけではなく、以前のバージョンを実行しているコントロールグループと比較してください。
Comparison approaches (best to worst):
1. Canary vs. control: split traffic, compare groups in real time (best)
2. Before/after: compare post-deploy metrics to pre-deploy window (good)
3. Historical: compare to same time last week (acceptable for trends)
4. Absolute thresholds: fixed thresholds regardless of baseline (fragile)
統計的有意性
ビジネス指標(コンバージョン、収益)では、サンプル数が少ないと結果にばらつきが生じます。結論を出す前に、統計的有意性が確認できるまで待ってください。
Minimum sample sizes for rollout decisions:
- Error rate: 1,000 requests (errors are rare events, need volume)
- Latency: 500 requests (more stable, converges faster)
- Conversion rate: 5,000 sessions (business metrics have high variance)
- Crash rate: 10,000 app launches (crashes are rare events)
Rule of thumb: if you don't have enough traffic at 1% to reach
significance in 30 minutes, increase to 5% or extend the hold window.
ダークローンチ
ダークローンチでは、新機能を本番環境にデプロイしますが、ユーザーには表示しません。実際の本番トラフィックで新しいコードパスを実行しつつ、ユーザーへの影響を避けられます。
トラフィックのシャドーイング
受信リクエストを複製して新しいサービスに送信します。レスポンスを比較しますが、新しいレスポンスはユーザーに返しません。
Request flow:
User → Load Balancer → Production Service (returns response to user)
↘ Shadow Service (processes request, logs result, discards)
What to compare:
- Response status codes: shadow should match production
- Response body: diff for semantic equivalence (ignore timestamps, IDs)
- Latency: shadow should not be significantly slower
- Error rate: shadow should not produce more errors
並列実行
移行(新しいデータベース、新しいアルゴリズム、新しいサービス)では、本番環境で旧パスと新パスの両方を実行します。旧パスの結果をユーザーに返し、新パスは非同期で実行して差異をログに記録し、結果は破棄します。時間の経過とともに一致率を追跡し、切り替え前に99%以上の一致を目標にします。
Shadow launch timeline:
Week 1: Deploy shadow, start comparing, expect <50% match
Week 2: Fix mismatches, match rate should climb to 90%+
Week 3: Match rate stable at 99%+, handle remaining edge cases
Week 4: Cut over: shadow becomes primary, old becomes shadow
Week 5: Remove old path after 1 week of stability
アンチパターン
監視なしで本番環境をテストする
ダッシュボードやアラートなしで本番テストを実行するのは、計器を見ずに飛行するようなものです。テストが原因の問題も、ユーザーから報告されるまで気づけません。 対策: 監視は前提条件です。本番テストを追加する前に、エラー率、レイテンシ、主要なビジネスメトリクスをリアルタイムで確認できることを確かめてください。最初のテストを実行する前にアラートを設定してください。
ロールバック計画がない
「何か問題が起きたら修正をデプロイします」は、ロールバック計画ではありません。プレッシャーのかかる状況では、修正に時間がかかり、新たなバグを引き起こし、障害を長引かせる可能性があります。 対策: 本番テストやロールアウトにはすべて、5分以内に実行できる、文書化されたロールバックの仕組み(フィーチャーフラグの無効化、以前のデプロイへの復帰、トラフィックの再ルーティングなど)と、システムが実際に復旧したことを確認する検証手順が必要です(検証を参照)。
本番テストで破壊的な操作を行う
実際の注文を作成したり、実際のメールを送信したり、実際のユーザーデータを変更したりする本番テストは、テストではなく、発生を待つインシデントです。 対策: テストデータとしてフラグを付けた合成アカウントを使用してください。決済とメールにはサンドボックスモードを使用してください。作成したデータはフィクスチャのティアダウンで削除し、必ず実行されるようにしてください。テストを非破壊的にできない場合は、本番環境で実行すべきではありません。
成功した場合にしか実行されないクリーンアップ
アサーションの後に置かれたクリーンアップ処理は、アサーションが失敗すると実行されず、本来削除するはずのテストデータが残ってしまいます。test()の本体内でtest.afterEach()を呼び出すのも同じ落とし穴で、例外が発生するか、無視されます。
対策: テストの成否にかかわらず実行されるよう、ティアダウンは自動クリーンアップフィクスチャまたはfinallyブロックに配置してください。references/patterns.mdを参照してください。
本番前環境ではなく本番環境でテストする
本番テストは本番前テストを補完するものであり、置き換えるものではありません。本番前環境が壊れていて、使える環境がそこしかないため「本番環境でテストしている」のであれば、まず本番前環境を修正してください。 対策: 正常に動作する本番前環境を維持してください。本番環境でしか検証できないもの、つまり実際のトラフィック、実際のデータ量、実際のサードパーティ連携の検証に本番テストを使用してください。
比較を行わないカナリアデプロイ
トラフィックの1%にデプロイしても、カナリアのメトリクスを対照群と比較しなければ、肝心の目的を果たせません。問題を検出せずに、デプロイをゆっくり行っているだけです。 対策: カナリアのメトリクスは必ずベースラインと比較してください。並列表示のダッシュボードまたは自動カナリア分析ツール(Kayenta、Argo Rollouts analysis)を使用してください。
古くなったフィーチャーフラグ
完全にロールアウト済みでも削除されないフラグは蓄積していきます。1年後には、相互作用が不明なフラグが200個もあり、誰にも理解できない分岐ロジックがあらゆるコードパスに残っている状態になりかねません。 対策: フラグには作成時に必ず有効期限を設定してください。完全なロールアウト後、2週間安定したら、フラグと不要になった分岐を削除してください。フラグの経過期間を追跡し、有効期限を過ぎたフラグについてアラートを設定してください。
検証
最初の本番利用より前に、ロールバック経路が実際に発動することを証明してください。一度も発動させたことのないロールバックは、仮説にすぎません。まずは最小限の確認から始めます。
- ステージングでガードレールに抵触させます。 同じ
automatic_rollbackポリシーに接続されたステージングロールアウトで障害を注入します(例:error_rate_5xxを2x_baselineより高くする、またはヘルスチェックを3回失敗させる)。for:の期間内にロールバックアクションが発動することを確認します。 - 復帰した状態を確認します。 ヘルスチェックのスモークテストを再実行し、
status === 'healthy'と以前のversionをアサートします。フラグプラットフォームまたはデプロイを照会し、以前のビルドが配信されていることを確認してください。思い込みで判断してはいけません。 - メトリクスが回復したことを確認します。 エラー率、P99 レイテンシ、クラッシュ率が、デプロイ前の範囲内に戻っていることを確認します。
- 通知が送信されたことを確認します。 ロールバックのアラートがオンコールのチャンネル(Slack/PagerDuty)に届いたことを確認します。
- スモークテストがパイプラインに接続されていることを確認します。 ステージングを対象にデプロイジョブを実行し、デプロイ後のスモークテストステージが実行され、昇格をゲートすることを確認します。
npx playwright test production-smoke.spec.tsが終了コード 0 で終了することを確認します。
ステップ1~4をステージングで実証できない場合、ロールバックは未検証であり、ロールアウトの準備はできていません。
エージェント向けの近道: LaunchDarkly、GrowthBook、Unleash、Flagsmith、Statsig、Harness FME 向けのベンダー MCP サーバーがあり、これらを使うと、ダッシュボードを手動で操作する代わりに、AI エージェントがこれらの確認中にフラグを切り替え、ロールアウトメトリクスを直接読み取れます。
完了条件
- 機能フラグのロールアウト計画が、各段階の明示的な割合(1% → 10% → 50% → 100%)と、段階ごとに指定されたガードレールメトリクスとともに文書化されていること。
- 昇格とロールバックの判断で、メトリクスを手動で比較する必要がないように、自動化された合格/不合格基準を用いてカナリア分析が設定されていること。
- 本番スモークテストが、デプロイのたびにパイプラインのステージとして実行されること(デプロイ前の CI でのみ実行するのではなく)、また、本番環境に対してステージが終了コード 0 で終了すること。
- ロールバックのトリガー条件が定義・文書化され、最初の本番利用の前に、検証のステージングでのドライラン(ガードレールに抵触 → ロールバックが発動 → 復帰した状態と回復したメトリクスを確認)を通じて、正しく発動することが実証されていること。
- 本番テストデータの方針が文書化されており、合成ユーザーと匿名化された実ユーザーのどちらを使用するか、また、それらを分析と課金から除外する方法が指定されていること。
参照ファイル(references/ 内)
- rollout-policy.md — 昇格基準の完全な YAML、自動ロールバックのトリガー、エラーバジェット/SLO ゲートの設定。
- patterns.md — フラグの ON/OFF と組み合わせのテスト、
production-smoke.spec.tsスイート、合成アカウントの規約、フィクスチャを使った非破壊的な作成・検証・クリーンアップのパターン。
関連スキル
- release-readiness — リリース全体の Go/No-go 判定です。本番テストは、その中でデプロイ後の検証ステップとして実施します。ロールアウトの仕組みではなく、リリースチェックリストについては、こちらを参照してください。
- synthetic-monitoring — ロールアウト完了後に継続的に実行される、定期的なプローブです。進行中のロールアウトの安全性ではなく、継続的な SLA 検証については、こちらを参照してください。
- observability-driven-testing — 本番のトレースとログを、新しいテストを設計するための入力として使用します。安全にリリースする方法が必要な場合ではなく、テレメトリーからテスト対象を判断する場合にこちらを参照してください。
- qa-metrics — ガードレールメトリクスとロールアウト基準を、ダッシュボードと KPI に反映する方法を扱います。
- ci-cd-integration — スモークテストステージとロールアウトゲートをパイプラインに接続します。
- test-environments — 本番テストを補完するものであり、決して置き換えるものではない、本番前の環境です。