Skip to content
Latchkey

テストにおけるrace conditionとは?解説

race conditionは、結果が処理の相対的なタイミングや順序に依存する欠陥で、速度、スケジューリング、並列度によって結果が変わります。

race conditionはflakyなテストの主要な原因です。バグは処理が特定の順序でインターリーブしたときにしか現れないため、遅いrunnerで、重い並列度のもとで、あるいは一見ランダムに、断続的に表面化し、再現するのが非常に厄介になります。

race conditionとは何か

race conditionは、2つ以上の処理が異なる順序で完了しうり、少なくとも1つの順序が誤った結果を生むときに存在します。「レース」はそれらの間で起こり、勝った方が結果を変えます。正しいコードは、どちらが先に終わるかに依存してはいけません。

なぜflakinessを引き起こすのか

テストはしばしば、結果をassertする前に処理が終わっていると仮定します。処理が非同期の場合、速いマシンは間に合わせられても、遅いマシンや負荷の高いマシンでは間に合わないため、同じテストがローカルでは通りCIで失敗します。結果はタイミングに依存し、それがまさにflakyの定義です。

テストのどこに現れるか

  • 非同期処理、タイマー、promiseが解決する前にassertすること。
  • 分離なしに並列テストやworkerによって変更される共有状態。
  • 並行して到着するアイテムの順序に依存すること。
  • 実際の条件を待つ代わりに固定のsleepに頼ること。

どう修正するか

固定のsleepを、実際の条件への明示的な待機に置き換えます。テストが干渉できないよう共有状態を分離します。言語がrace detectorを提供しているなら使います。目標は、テストを決定論的にして、その結果がもはやレースの勝者に依存しないようにすることです。

Latchkeyの視点

race conditionはあなたのテストやコードの本物のバグなので、Latchkeyがあなたの代わりに修正することはできません。しかしその周りの一時的なインフラの失敗を自己修復することで、Latchkeyはノイズを減らし、残る失敗が、修正する価値のある本物のrace conditionであることをより明確にします。

重要なポイント

  • race conditionは、結果をタイミングや順序に依存させます。
  • ローカルでは通り、CIで失敗するflakyなテストの主要な原因です。
  • 非同期のassertion、共有状態、固定のsleepがよくある原因です。
  • 実際の条件を待ち、共有状態を分離することで修正します。

関連ガイド