非決定的テストとは? 解説
非決定的テストは、時間、乱数、順序、外部状態など制御されていない何かに依存するため、同一の入力に対して異なる結果を返すことがあります。
決定性とは、同じ入力が常に同じ出力を生み出す性質です。それを欠くテストは構造的に信頼できません。コードが正しくても、テスト結果は変動しうるのです。非決定性は、ほとんどのフレーキーテストの背後にある根本的な仕組みです。
決定性の定義
決定的なテストは、同じコードと入力が与えられれば、常に同じ結果を生み出します。非決定的テストはそうではありません。その結果が、制御していない要因に影響されるからです。その隠れた依存こそがflakinessの根源です。
非決定性の原因
- runごとに変わる実際の実時間、タイムゾーン、または日付。
- runごとに変動する、シードされていない乱数やハッシュ順序。
- 毎回異なる形で交錯する並行性やテストの順序。
- 変動するデータを返す実際のネットワーク、ファイルシステム、またはサードパーティサービス。
ただのバグより厄介な理由
決定的なバグは一貫して失敗し、再現も修正も分かりやすいものです。非決定的テストは時々しか失敗しないため、再現が難しく、「ただのflaky」として片付けられやすく、スイート全体への信頼を損ないます。断続性こそが問題なのです。
テストを決定論的にする
時間を注入して固定します。乱数は明示的にシードします。外部サービスはスタブ化します。状態を分離し、共有グローバルを避けます。固定のsleepではなく実際の条件を待ちます。それぞれの変更が制御されていない入力を1つずつ取り除き、やがてテストは毎回同じ結果を生み出します。
Latchkeyの観点
テスト内の非決定性はコード側の問題であり、retryでは本当には修正できません。Latchkeyの自己修復するマネージドrunnerは代わりに、一時的および機械的な障害をretryすることでテストを取り巻く環境的な非決定性を取り除き、一度きりのblipがbuildを失敗させないようにします。そして残った変動が明確にテストを指し示すようにします。
重要なポイント
- 非決定的テストは、同一の入力に対して異なる結果を出します。
- 時間、乱数、順序、外部状態が通常の原因です。
- その断続性が、一貫したバグより修正を難しくします。
- 制御されていない各入力を制御して決定性を取り戻します。
関連ガイド
What Is a Flaky Test? Causes and Fixes ExplainedA flaky test passes and fails on the same code without any change. Learn what causes flakiness, why it erodes…
What Is a Race Condition in Tests? ExplainedA race condition is a bug whose outcome depends on timing or ordering. Learn why race conditions make tests f…
What Is Test Isolation? ExplainedTest isolation means each test runs independently without leaking state to others. Learn why isolation preven…
What Is a Deterministic Failure? ExplainedA deterministic failure happens every run because the cause is in the code or config. How it differs from a t…