はじめに
ユニットテストも結合テストも書き、境界値分析や同値分割の基本も押さえている。
それでも本番ではバグが出る ── そういう経験は自分も繰り返してきました。
後から見るとバグは偏っていて、「特定機種でだけ落ちる」「特定の地域で文字化け」「ピーク時に遅延」「AIが想定外の応答」── 同じテストを流しても再現しません。
「テストが足りない」というより「ドメイン特性に応じた専門テストが組み込まれていない」のが原因に思えます。
この記事では専門領域のテストを、ドメイン名で並べる代わりに「基本テストでは捕捉しきれない4つの破綻要因」という軸で整理してみます。
TL;DR
- 基本テストで捕捉しきれない破綻要因は4つに整理できる ── 環境の不確実性/入力モードの広がり/非機能要件の固有制約/挙動の予測可能性の低さ
- 自プロダクトのリスクが大きいクラスタから順に、対応する専門手法(in-the-wild、UX/アクセシビリティ、性能/i18n、AI/MBTなど)を選び取る
- 専門テストは基本テストの置き換えではなく補完。
「全部やる」のではなく「破綻要因に応じて選ぶ」
ドメイン固有の破綻要因 ── 4つの軸で整理する
専門領域のテストを「モバイル」「Web」「セキュリティ」のようにドメイン名で並べると、
独立した話題に見えてしまいます。
実際には複数のドメインに共通する「基本テストでは届かない原因」があり、
それを軸にすると整理が楽になると感じました。
4つの破綻要因と、それぞれが顕在化する代表ドメインを地図として示します。
┌─────────────────────────────┬──────────────────────────────────────────┐
│ 破綻要因(クラスタ) │ 顕在化する代表ドメイン │
├─────────────────────────────┼──────────────────────────────────────────┤
│ ① 環境の不確実性 │ モバイル / Web / リアルタイム │
│ ラボでは再現しない多様性 │ (デバイス・OS・ブラウザ・回線・割り込み) │
├─────────────────────────────┼──────────────────────────────────────────┤
│ ② 入力モードの広がり │ モバイルUX / アクセシビリティ │
│ キーボード/マウス前提を超える │ (タッチ・ジェスチャー・音声・触覚補助) │
├─────────────────────────────┼──────────────────────────────────────────┤
│ ③ 非機能要件の固有制約 │ 国際化 / 性能 / セキュリティ │
│ 機能テストの延長で届かない │ (i18n・負荷・ストレス・脅威) │
├─────────────────────────────┼──────────────────────────────────────────┤
│ ④ 挙動の予測可能性の低さ │ AIシステム / 仮想環境(VR・ゲーム) │
│ 期待結果を厳密に書き下せない │ (確率的応答・主観的体験・状態爆発) │
└─────────────────────────────┴──────────────────────────────────────────┘
ひとつのドメインが複数のクラスタに跨るのは普通です。
モバイルアプリは①②の両方を抱え、
生成AIを組み込んだWebサービスは①③④を同時に抱えます。
「自プロダクトはどのクラスタの色が濃いか」を知っておくと、
専門テストの優先順位がつけやすくなります。
各クラスタの具体的な手法は以降で扱い、
自プロダクトへのマッピング方法は最後の戦略セクションで整理します。
環境の不確実性 ── ラボと本番のギャップ
「ローカルもCIもステージングも通ったのに本番で壊れた」
── このパターンの多くは、テスト環境が本番の多様性を再現できていないのが原因です。
多様性はドメインによって違う形で現れます。
- モバイル: デバイス・OS・キャリア・電力状態
- Web: ブラウザ・拡張・画面サイズ・CDNキャッシュ
- リアルタイム系: 割り込み・通信遅延
このクラスタは「多様性そのもの」「割り込みからの復旧」「Web特有の3観点」に分けると見通しがよくなります。
多様な実行環境にどう向き合うか ── in-the-wildテストとデバイスマトリクス
実環境とラボのギャップは、たとえばこんな形で具体化します。
| 多様性の軸 | ラボでは見えにくいバグの典型例 |
|---|---|
| デバイス・OS | 特定機種のGPUドライバ起因のレンダリング崩れ/OS別の権限ダイアログ仕様差 |
| ブラウザ・拡張 | Safari固有のJS挙動/広告ブロッカ拡張による要素消失 |
| ネットワーク | 高遅延・パケットロス時のタイムアウト挙動/キャリア別のNAT/プロキシ |
| 電力状態 | 低電力モードでバックグラウンド処理が間引かれる/発熱起因の遅延 |
| ロケーション | CDNキャッシュの地域差/時刻・タイムゾーン依存の境界バグ |
これらのギャップを埋めるための代表的な手段が
in-the-wildテストとWDPM(Weighted Device Platform Matrix) です。
in-the-wildテスト
実ユーザーが普段使う環境・デバイス・ネットワークでテストする手法。
テスト対象のデモグラフィクス(地理・年齢・端末種別など)を本番ユーザー層に合わせるのがポイントです。
実装手段は、以下の組合せで運用します。
- クラウド実機ファームでの自動実行:クラウド経由で実機やブラウザを借りられるサービス(後述のAWS Device FarmやBrowserStackなど)を、CIから自動で叩く方式
- 本番ユーザーの実測(RUM: Real User Monitoring):本番環境で実際のユーザーが触ったときの応答時間やエラーを記録・収集する仕組み
- フィーチャーフラグによる段階的ロールアウト:新機能をいきなり全員に出すのではなく、設定ファイル(フラグ)で一部のユーザーにだけ有効化して様子を見る方式
- NDA付きクラウドソーシング:守秘契約(NDA)を結んだ外部のテスターに、実機で触ってもらって不具合を報告してもらう方式
デバイスマトリクスの優先順位付け
スマホやブラウザの全組合せをテストするのは現実的ではありません。
たとえば1機種×1OSで1週間かかるなら、10機種×5OSで半年かけても回しきれません。
そこで使われるのが WDPM(Weighted Device Platform Matrix) です。
よく使われるデバイスとOSに「人気度」のような重み(ユーザー数や売上シェアに比例した数値)をつけ、その積(重み同士の掛け算)が大きい組合せから優先的にテストします。
OS-A(重み3) OS-B(重み4) OS-C(重み7)
Device-1(7) N/A 28 49
Device-2(3) 9 N/A N/A
Device-3(4) 12 N/A N/A
Device-4(9) N/A 36 63 ← 最優先
「人気」は時系列で変わるので、半年〜1年に一度は重みを再評価します。
エミュレータ/シミュレータと実機の使い分け
エミュレータは実機の内部処理ごとPC上で真似する仕組み、
シミュレータは画面と動作だけを真似する仕組みです。
どちらも実機とは得意領域が違うので、役割分担で使うのが基本です。
| 観点 | エミュレータ/シミュレータ | 実機 |
|---|---|---|
| コスト・並列性 | 安価で並列実行しやすい | 台数・運用コストが高い |
| CPU/GPU性能・バッテリー | 再現困難 | 正確に観測できる |
| センサー・ストア環境 | 再現困難 | 本番に近い |
| 性能・互換性・GUI | 一次スクリーニング向け | 最終確認に必須 |
AWS Device FarmやBrowserStackのようなクラウド実機ファームは、
CI/CDから世界中の実機・ブラウザに自動アクセスできる選択肢です。
社内に物理デバイス棚を抱えるより現実的で、
新規プロダクトの初期段階では特に有力な選択肢になります。
例外的な状況からどう復旧するか ── アラート・割り込み・リカバリーテスト
環境の不確実性は「多様性」だけでなく「割り込み」としても現れます。
通話の着信、プッシュ通知、Wi-Fi切断、低電力アラート、カレンダー通知、OSの強制終了
── 本番ではごく日常的に発生します。
対応するテスト観点は2つあります。
- アラート・例外条件のテスト: 自アプリが他からの割り込みを受けた状態で動くかを意図的に試す。シミュレーションを用意しつつ、最終的には実機確認が必要
-
リカバリーテスト: 障害を意図的に発生させて復旧能力を検証する
- 自動復旧の場合:再初期化、チェックポイント、データ復旧、再起動の正しさを確認
- 人手介入が必要な場合:MTTR(Mean Time To Repair/Recovery, 平均修復時間)が許容範囲内かを評価
クラウド上で動くサービスでは、
カオスエンジニアリング という手法が広がっています。
本番に近い環境で、意図的にサーバーを止めたりネットワークを切ったりして「障害が起きても自動で復旧できる作りになっているか」を検証するアプローチです。
代表的なツールが Netflix が公開した Chaos Monkey で、
リカバリーテストを開発時だけでなく運用フェーズにまで広げたものといえます。
Webで固有に難しい環境多様性 ── 3観点で別々に現れる
Webは「クライアント環境を制御できない」点でモバイル以上に多様性が大きい領域です。
ブラウザ、バージョン、拡張機能、画面サイズ、回線品質、ロケール、CDNキャッシュ
── これらが任意の組合せで現れます。
重要なのは、Webの環境多様性はコンテンツ/インターフェース/ナビゲーションの3観点に別々に作用すること。
3観点に分けて管理しないと、見落としが出やすくなります。
| 観点 | 何を検証するか | 環境多様性の現れ方 |
|---|---|---|
| コンテンツテスト | テキスト・画像・動画・データの正しさ | CDNキャッシュで古いデータが残る/ロケール別の翻訳差/動的生成データの不整合 |
| インターフェーステスト | フォーム・ボタン・スクリプト等のUI部品の動作 | ブラウザ別のJS挙動差/拡張機能による干渉/画面サイズによるレイアウト崩れ |
| ナビゲーションテスト | 画面遷移経路が、ユーザーカテゴリごとに目的を達成できるか | 外部からの直接遷移/戻る・進むボタンの挙動差/サイトマップ経由の到達経路 |
「インターフェーステストのついでにナビゲーションの間違いに気付く」ことを期待しないのが、この分割の趣旨です。
入力モードの広がり ── キーボード/マウス前提では捕捉できない
入力はもうキーボードとマウスだけではありません。
タップ、スワイプ、ピンチ、仮想キーボード、音声、視線、コンテキスト(位置・時刻・周囲音)まで含み、それぞれ独自の検証課題があります。
さらに裏側には、これらの入力が使えない/使いにくい利用者へのアクセシビリティが表裏で存在します。
入力モードごとの主要なテスト観点は次のようになります。
| 入力モード | 主なテスト観点 | 自動化のしやすさ |
|---|---|---|
| タッチ/ジェスチャー | 位置・サイズ依存のヒット判定/視覚障害者への代替フィードバック | 低(テストハーネスが必要) |
| 仮想キーボード | 入力中の画面遷移/予測変換/訂正のしやすさ | 中 |
| 音声入力 | 環境ノイズ/発話の個人差/誤認識時のクラッシュ耐性 | 低(実環境必須) |
| コンテキストアウェア | 位置・時刻・周囲音などの環境情報に応じた挙動分岐 | 中 |
| アクセシビリティ | 代替テキスト/色以外での情報伝達/拡大・コントラスト/代替入力 | 高(自動チェッカ+実機) |
コンテキストアウェアは、位置・時刻・周囲音などの環境情報に応じて挙動を変えるアプリの性質を指す用語で、モバイルやIoTでは標準的な前提です。
タッチ/ジェスチャー/仮想キーボードのテスト
ジェスチャーテストは厄介です。
画面サイズ・解像度・直前の状態に依存して挙動が変わり、
自動化ツールでの再現も、ログ記録や再生も難しい。
視覚障害のあるユーザーへの代替(触覚・聴覚フィードバック)も検証対象に入ります。
現実的な対応は地道な組合せになります。
- ジェスチャーイベントを呼び出すテストハーネスを書く
- 対象デバイスを実機で触る
- ユーザーストーリーをテストスクリプトに落とす
テストハーネスは、テスト対象のコードを動かすために、
入力を疑似的に発生させる仕組みのことです。
下のコード例の tap() や swipe() がそのハーネスで、
本物の指タッチの代わりにタッチイベントを発生させます。
ハーネスのイメージはこんな形です。
class GestureHarness:
def __init__(self, app):
self.app = app
def tap(self, x, y):
self.app.dispatch_event("touchstart", x=x, y=y)
self.app.dispatch_event("touchend", x=x, y=y)
def swipe(self, x1, y1, x2, y2, duration_ms=200):
self.app.dispatch_event("touchstart", x=x1, y=y1)
for px, py, t in interpolate(x1, y1, x2, y2, duration_ms):
self.app.dispatch_event("touchmove", x=px, y=py, t=t)
self.app.dispatch_event("touchend", x=x2, y=y2)
def pinch(self, cx, cy, start_dist, end_dist):
# 2本指の対称的な座標変化としてシミュレート
...
# 使い方
h = GestureHarness(app)
h.swipe(100, 400, 300, 400) # 右スワイプで次ページへ
h.pinch(cx=200, cy=300, start_dist=50, end_dist=200) # 拡大ジェスチャー
assert app.current_page == "page-2"
ハーネスでCI上の最低限の動作を担保しつつ、画面サイズ違い・誤タップ耐性・視覚的フィードバックの自然さは実機で人が触って確認する。
この役割分担が落としどころです。
仮想キーボードの検証観点も独特です。
- 画面に出たときの重要情報の隠れ
- 入力中の遷移での内容消失
- 誤入力訂正やクラッシュ耐性
- 予測変換の精度
- 物理キーボード・音声入力など代替手段への切替
音声入力のテスト
音声入力にはボイスメール記録、離散単語認識(メニュー選択)、連続音声認識(ディクテーション)の3形態があり、それぞれ難度も検証ポイントも違います。
検証要因は音声特有のものに集中します。
- 環境ノイズ(静かな部屋/屋外/車内で認識率が変わる)
- 個人の発話差(アクセント・声の高さ・話速・滑舌)
- 誤認識時のクラッシュ耐性
- 多数のユーザー×多数の環境での誤り率収集
LLMベースの音声アシスタントが一般化したことで、音声入力テストは「認識精度」だけでなく「生成された応答の妥当性」までを範囲に含むようになりました。
これはAIシステムのテストと地続きです。
すべてのユーザーが使える状態か ── アクセシビリティテスト
ここまでは「より多様な入力を取り込む」方向で入力モードの広がりを見てきました。
その裏側には、ある入力/出力モードが使えないユーザーに別のモードで等価な情報・操作を提供する、というアクセシビリティの問題があります。
視覚・聴覚・運動・認知などの困難を持つユーザーが使えるかを検証する観点です。
WCAG(Web Content Accessibility Guidelines) などのガイドラインが基準として使われます。
代表的な観点は次のとおりです。
- 非テキスト要素のテキスト代替(alt属性等)
- 色以外での情報伝達
- 高コントラスト・拡大表示
- 代替入力への対応
- 点滅コンテンツの回避
検証は3層に分けて重ねるのが現実的です。
- 自動チェッカ(axe-core、Lighthouseなど)で機械的な違反を一掃する
- スクリーンリーダー(VoiceOver、TalkBack、NVDA)での実機検証で、読み上げ順や操作可能性を確認
- 専門家レビュー+代表的な障害特性を持つテスターによる試験で、実利用感を評価
導入コストの低い順に1→2→3と積み重ね、
3まで踏むかはプロダクトの重要度で判断します。
1だけで止めると「機械的には合格しているが実用性は微妙」になりやすい、
という関係です。
非機能要件の固有制約 ── 機能の正しさだけでは終わらない
機能テストが緑でも、本番では「遅い」「重い」「攻撃される」「現地で読めない」といった非機能の問題でユーザーが離脱します。
非機能要件は機能テストの延長線上にはなく、それぞれ専用の観点と道具立てが必要だ
── ということを、自分は何度かのトラブル対応で思い知らされてきました。
ここでは国際化/パフォーマンス/セキュリティを順に取り上げます。セキュリティは別領域として深く掘られる体系があるため、概念の位置づけまでに留めます。
国際化テスト ── 翻訳の正しさだけが論点ではない
「日本語版を出した後で多言語対応する」というアプローチは、
後から負債が膨らみがちです。
文字列のハードコード、幅固定のUI、日付フォーマットの暗黙の前提
── これらは多言語化のタイミングで一気に表面化します。
用語は2つが軸になります。
- 国際化(Internationalization, i18n): 設計段階で「将来複数の地域・言語で動かせる構造」になっているかを検証する観点
- ローカライゼーション(Localization, L10n): 特定地域向けに翻訳・通貨・規制などをアダプトした結果の正しさを検証する観点
検証範囲を一望すると次のようになります。
| 観点 | 確認内容 |
|---|---|
| 文字列 | ハードコードされていないか/外部リソースに分離されているか |
| 文字方向 | LTR/RTL(アラビア語・ヘブライ語)への対応 |
| 文字長 | ドイツ語など長い言語でレイアウトが崩れないか |
| 日付・通貨・住所・電話番号 | 地域別フォーマットの正しさ |
| ソート順 | 言語ごとのコレーション(並び順ルール) |
| フォントレンダリング | 字形・合字・絵文字の表示崩れ |
| 法規制 | GDPR、各国の個人情報保護法、税制への対応 |
各国にテスト拠点を構えるのは高コストなので、
社外の協力者に機密保持の契約を結んでもらい、実機で触って不具合を報告してもらう方式もよく使われます。
パフォーマンステスト ── 負荷とストレスは違う
パフォーマンステストの目的は2つあります。
負荷(同時利用者数、トランザクション数、データ量)が増えたときの挙動を理解することと、改善のためのメトリクスを集めることです。
そして「負荷」と「ストレス」は別物で、混同するとテスト計画の解像度が一段下がります。
リソース利用率/応答時間
▲
崩壊点 ──────┼───────────● ← ここで壊れ方を観察するのがストレステスト
│ /
想定上限 ────┼─────●─ ← この線まで上げて反応を見るのが負荷テスト
│ /
通常運用域 ───┼─●─ ← 普段はこのあたりで動く
│
└────────────► 負荷量(同時ユーザー・Tx数・データ量)
負荷テスト(Load testing)
通常運用域内のさまざまな負荷条件で応答時間・スループットを計測します。
同時ユーザー数N、単位時間あたりのトランザクション数T、1Txあたりのデータ量Dから、
スループットPを概算します。
そこからサーバ側のネットワーク帯域が耐えられるかを確認します。
ストレステスト(Stress testing)
通常運用域を超える負荷をかけ、どこで・どう壊れるかを観察します。
複数アプリの同時実行、極端な大量トランザクション、極端なデータ量など想定外の状況をあえて作ります。
重要なのは「壊れ方」
── セキュリティの低下を伴わずに段階的に劣化(graceful degradation)するかです。
ロードバランサが落ちたときに認証が素通りになる、といった事故を避ける観点です。
2020年代の文脈では3つの実務的な広がりがあります。
Core Web Vitals(LCP, INP, CLSなど)はWebの体感パフォーマンスを表すGoogle標準指標で、SEOにも影響します。
APM(Application Performance Monitoring)(New Relic、Datadog、Sentryなど)は本番環境の性能を継続的に観測する仕組みで、「負荷テストはリリース前、APMはリリース後」という役割分担です。
負荷テストの自動化ではk6、Locust、JMeterなどをCIに組み込む流れも一般化しています。
セキュリティテスト ── 概念だけ押さえる
セキュリティテストは「攻撃に耐えるか」を能動的に検証するテストで、
脆弱性が悪用されるコストを攻撃者の利得より高くする、
という設計思想がベースにあります。
攻撃対象は層ごとに性質が違うので、テスト設計では層を意識して防御技術と紐づけます。
| 層 | 主な攻撃面 | 関連する防御技術 |
|---|---|---|
| クライアント | XSS、改ざん、入力バリデーション回避 | 認証、入力検証、サンドボックス |
| ネットワーク | 盗聴、中間者攻撃、DDoS | 暗号化(TLS)、ファイアウォール |
| サーバ | SQLインジェクション、権限昇格 | 認可、最小権限、ログ監査 |
セキュリティの世界には脅威を洗い出すモデリング手法や、
ライフサイクル全体に安全策を組み込む方法論が体系として整備されています。
前者は要求分析の段階から、後者は設計・実装・運用にまたがって適用するものです。
深さも幅もあるため、業務上クリティカルなアプリでは外部の専門ベンダーへの委託も合理的な選択肢になります。
挙動の予測可能性の低さ ── 「期待結果」を厳密に書き下せない領域
基本テストは「入力に対してこの出力が返るべき」という期待結果を厳密に書けることを暗黙の前提にしています。
ところがAIシステムの応答や仮想環境の主観的体験では、
その期待結果を一意に書き下せません。
「期待結果が確率的・主観的にしか決まらない領域」では、
検証戦略そのものを変える必要があります。
このクラスタの3つの典型例と回避策を先に俯瞰します。
| 典型例 | 何が「書き下せない」のか | 回避策の方向性 |
|---|---|---|
| AIシステムの確率的応答 | 出力が入力と1対1に決まらない/自由形式 | 許容範囲のセマンティクス評価/代表入力での経時観測 |
| プレイアビリティ(ゲーム・VR) | 「楽しい」「没入できる」が品質の中核 | 代表ユーザーによる主観評価/詰まる場所の観察 |
| 主観的UX(仮想体験全般) | 期待値そのものが個人差を持つ | 専門家レビューと代表ユーザーの二重チェック |
AIシステムのテスト ── 静的・動的・データの組合せ
AI(機械学習・データマイニング・統計・ヒューリスティック・ルールベース)を含むシステムは、データ依存性が高く、組合せ爆発で全パターンの確認が不可能です。
だからこそ検証は実行と非実行の両面から組み立てます。
- 静的テスト: 実行せずレビューで検証。ドメイン専門家がデータ表現と使われ方に同意しているか、ユースケースの入出力とコードのマッピングが整合しているかを確認
- 動的テスト: 実際にコードを実行し、専門家が「この振る舞いは期待通り」と判定。AIが人間の知らない関係を発見した場合は、専門家が検証してから安全クリティカル領域での利用を判断
シミュレーションでも全組合せは網羅できません。
本番でユーザーが「この判断はおかしい」と通知できる仕組みと、プログラム状態を収集して改修に使える仕組みを、設計段階で組み込んでおくのが実践的です。
LLM/生成AI固有の論点も増えてきました。
生成出力を別モデルに評価させる「LLM-as-a-judge」(judge自身のバイアスがあるため人間評価との二重チェック併用が現実的)、プロンプトインジェクション耐性、ハルシネーション検査、モデルバージョン更新による出力分布の退行検出、本番運用後の入力分布変化を監視するデータドリフト対策、といった観点です。
モデルベーステスト(MBT) ── 状態遷移をテストの起点にする
状態に依存して挙動が変わるアプリでは、
テストケースを直感で書き下すと網羅性に大穴が空きます。
モデルベーステスト(MBT) は、振る舞いモデル(特にUML状態遷移図)をベースにテストケースを生成するブラックボックス技法です。
MBTの5ステップはこんな流れです。
適用領域はイベント駆動の挙動が中心になるアプリ全般で、コンテキストアウェアなモバイルアプリ、対話的UI、ステートフルなWebフロントが典型。
AIシステムにも一部適用されます。
MBTをこのクラスタに置くのは、振る舞いモデルがあれば「挙動の予測」を構造化でき、「全パターンを書き切れない」状況に組織的に対応できるからです。
仮想環境とプレイアビリティ ── 主観的体験をどう検証するか
VR、AR、ゲーム、シミュレーションといった仮想環境では、「楽しい/没入できる/使いやすい」といった主観的指標が品質の中核になります。
期待結果が「楽しい」では、ユニットテストでの検証は難しい。
プレイアビリティテストでは、ユーザビリティ・ストーリー・戦略・メカニクス・リアリティ・グラフィック・サウンドの総合評価で見ます。
本番ユーザー層と専門家ユーザーは別物なので、専門家レビューだけでは不十分です。
ベータ/アクセプタンステストに近い形で、代表的なエンドユーザーが実際に触り、開発者は中断せずに観察するのが基本です。
観察の焦点は「プレイヤーが詰まる場所」。動作が止まる瞬間をワークフロー上で記録し、後で原因と回避経路を分析します。
評価の枠組みは、ユーザビリティテストの観点を流用しつつ、各観点で質的評価を取る拡張版です。
| 観点 | 何を見るか |
|---|---|
| 操作性(Interactivity) | 入力に対する反応の自然さ |
| レイアウト(Layout) | 要素の配置がプレイ/体験の妨げになっていないか |
| 可読性(Readability) | テキストやアイコンが状況下で読み取れるか |
| 美的感覚(Aesthetics) | 世界観・没入感を損なわないか |
| フィードバック(Feedback) | プレイヤーの行動への手応えが返るか |
| アクセシビリティ(Accessibility) | 多様なユーザーが体験できるか |
| 信頼感(Trustworthiness) | 不安・不快を与える挙動がないか |
戦略の組み立て ── 自プロダクトに合わせて選び取る
4つの破綻要因に等しくテストリソースを投入するのは現実的ではありません。
自プロダクトの破綻要因を見極めて戦略を組み立てる視点を整理します。
自プロダクトの破綻要因をマッピングする
4クラスタ × リスクの大きさで自プロダクトの状況をマッピングします。
リスク: 小 中 大
┌──────┬──────┬──────┐
① 環境の不確実性 │ │ │ │ ← in-the-wild / WDPM / クラウド実機 /
│ │ │ │ リカバリー・カオス / ブラウザマトリクス
├──────┼──────┼──────┤
② 入力モードの広がり│ │ │ │ ← ジェスチャー/仮想KB/音声テスト /
│ │ │ │ アクセシビリティ自動チェッカ + 実機
├──────┼──────┼──────┤
③ 非機能要件の制約 │ │ │ │ ← 国際化テスト / 負荷・ストレス /
│ │ │ │ APM・Core Web Vitals / セキュリティ
├──────┼──────┼──────┤
④ 挙動の予測可能性 │ │ │ │ ← 静的・動的テスト / MBT /
│ │ │ │ ベータ・アクセプタンス / 本番監視
└──────┴──────┴──────┘
※ 上記4クラスタ全てに薄く効く横断的手法として
アルファ/ベータ/in-the-wild がある(後述)
各クラスタの問いは次のような切り口になります。
- 環境の不確実性: クライアント環境を制御できるか/実機・ブラウザ・地域の多様性は大きいか
- 入力モードの広がり: タッチ/音声/コンテキスト依存の入力があるか/アクセシビリティ要件はあるか
- 非機能要件: 性能要件は厳しいか/多言語展開はあるか/規制対応が要るか
- 挙動の予測可能性: AI/機械学習要素はあるか/主観評価が品質の中心か
リスクの大きいクラスタから対応手法を選んでいきます。
横断的に効く手法群 ── アルファ/ベータ/in-the-wild
4クラスタ全てに薄く効く横断的な手法もあります。
代表は次の3つです。
- アルファテスト: 開発者の管理下で代表ユーザーが触る
- ベータテスト: 実ユーザーが実環境で実利用する
- in-the-wild: 本番ユーザー層に近い環境・地域で広く触ってもらう
各クラスタに別の角度で効きます。
- 環境の不確実性: 実デバイス・実ネットワークでの破綻発見
- 入力モード: 想定しない入力パターンの発見
- 非機能要件: 実利用負荷・実回線・実ロケールでの現れ方の発見
- 挙動の予測可能性: 主観評価・許容範囲外応答の収集手段
基本テストとの組合せ方
専門テストは基本テスト(単体・結合・ホワイト/ブラックボックス)の置き換えではなく補完です。
基本テストが緑でも本番でバグが出るのは「基本テストが甘い」のではなく「基本テストが届かない領域がある」だけ、という関係です。
実務での配置は、自動化のしやすさと実行コストで分けると見通しがよくなります。
| 区分 | 配置先 | 例 |
|---|---|---|
| 基本テスト | CIで毎回回す(高速・決定論的) | 単体・結合・ホワイト/ブラックボックス |
| 専門テスト(自動化しやすい) | CIで頻繁に | クラウド実機、性能、アクセシビリティ自動チェック |
| 専門テスト(自動化しにくい) | 重要マイルストーンで実機・実ユーザー | ジェスチャー、音声、プレイアビリティ |
「全部やる」ではなく「自プロダクトの破綻要因に応じて、リスクの大きい順に投資する」 ── これが現実的な姿勢です。
おわりに
ドメインを章の順に並べると「あれもこれも必要」となりがちです。
ただ整理してみると、本質的には「基本テストでは届かない4種類の破綻要因」が主役で、それぞれに対応する手法群があるだけだと感じました。
最初の一歩としては、
直近1〜3か月の「本番でだけ起きたバグ」を4クラスタで集計するのが現実的です。
そしてトップ1クラスタに対応する専門手法を1つ選び、
CIまたはステージング工程に組み込みます。
「AI機能を組み込んだ瞬間に挙動の予測可能性のリスクが跳ね上がる」など、
マッピングしてみると初めて見える偏りもあります。
- 環境多様性が大きい → クラウド実機テスト連携をCIに追加
- 性能リスクが大きい → k6で代表シナリオの負荷テストを夜間ジョブ化
- まずは導入コストを抑えたい → アクセシビリティ自動チェッカ(axe-coreなど)はカバー範囲が広く入れやすい
専門テストはどれか1つが銀の弾丸ではありません。
基本手法を確実に持ったうえで、自分のドメインに固有の破綻要因に応じて道具を増やしていく ── という積み上げが現実的だと考えています。