SJ blog
backend
B

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

ハーネスエンジニアリング: 並列実行で壊れない隔離戦略

ポート・DB・ファイルをテスト単位で分離し競合を回避する。

一言結論

ポート・DB・ファイルをテスト単位で分離し競合を回避する。

背景

ポート・DB・ファイルをテスト単位で分離し競合を回避する。 ハーネス設計はテストコードの書き方ではなく、失敗を再現可能にするシステム設計です。並列実行の隔離を軸に、CI運用で効く具体策を整理します。

設計原則(網羅)

  1. 決定性: 時刻・乱数・外部I/Oを制御可能にする。
  2. 隔離性: テスト間で状態を共有しない。
  3. 観測性: 失敗時に原因追跡できるログ粒度を持つ。
  4. 再現性: seed/入力/依存バージョンを固定・記録する。
  5. 経済性: CI時間と調査工数の総和を最小化する。

具体例: CIでのみ失敗するケース

  • 現象: ローカルでは成功、CI並列実行時だけ失敗。
  • 原因候補: 時刻依存、順序依存、外部サービスの揺らぎ。
  • 対策:
    1. clock/seed/networkを注入可能なインターフェースへ。
    2. テストID単位で専用DBスキーマを割り当て。
    3. 失敗時に同seed再実行 + 依存スナップショット保存。

並列実行の隔離を実現する実装パターン

Arrange: 依存差し替え(clock, rng, io)
Act:     1シナリオ1目的で実行
Assert:  出力 + 副作用 + 監視ログを同時検証
Recover: seed再実行で再現性を確認

メトリクス駆動で改善する

指標定義目標
Flake率再試行で成功する失敗比率<2%
MTTD失敗から原因仮説まで30分以内
MTTR(test)テスト修正完了まで1営業日以内
CI先頭失敗検知失敗を最初に検知するまで10分以内

深掘り: チーム運用での落とし穴

  • Fixture肥大化: 便利関数が巨大化し、意図不明なテストが増える。
  • Golden崩壊: 期待値更新を機械的に承認し、退行を見逃す。
  • 過剰モック: 実環境差分を隠して本番不具合を誘発。
  • 計測欠如: Flake率未計測で“たまに落ちる”を放置。

ニッチ実務ノート

  • ネットワーク模擬では平均遅延よりもjitter/burst/drop率の設定が効く。
  • コンテナ並列でのポート競合は、動的ポート配布より名前空間分離が安定。
  • 時刻制御はUTC固定に加え、DST境界ケースを専用テスト化すると事故が減る。
  • Golden比較は完全一致と構造一致を使い分ける(例: JSONは順序非依存)。

現場導入チェックリスト

  • 失敗時にseedと依存バージョンを自動保存している
  • 外部I/Oを含むテストを層分離している
  • 並列実行時の隔離戦略(DB/FS/Queue)を持つ
  • Flake検知と隔離ルールがある
  • 毎週、失敗上位ケースをハーネス改善へ還元している

まとめ

ハーネスエンジニアリング: 並列実行で壊れない隔離戦略 はテスト追加よりも「失敗を工学的に扱う仕組み化」が本質です。決定性・隔離性・観測性を数値で運用すると、CIは品質ゲートとして機能し続けます。