テストの期待値は、実装を写す前に仕様の具体例から決める
入力と期待する振る舞いを先に具体化し、実際の結果と比べる。内部の関数名や呼び出し回数を固定するのは、それ自体が守りたい条件のときに絞る。
用語
- アサーション
- 実際の結果が期待する条件を満たすかを確認し、違えばテストを失敗させる仕組み。
- 振る舞い
- 入力に対する出力・エラー・状態変化など、利用する側から確認できる動作。
- リファクタリング
- 外から見える振る舞いを保ちながら、内部の構造を変えること。
図と例
仕様:小計3,000円以上は送料無料 → 例:2,999円・3,000円・3,001円 → 期待送料:500円・0円・0円 → 実際の結果をアサーションで比較
仮定の例:送料は小計3,000円以上なら0円、それ未満は500円。2,999→500、3,000→0、3,001→0を確認する。内部の判定を関数へ分けても、この期待値は変わらない。実装が誤って「3,000円より大きい」としていれば、3,000円のケースが検出する。
実際のサービス・製品では
解説
最初の単体テストやバグ修正の回帰テストに使う。仕様が曖昧なら、期待値をコードから推測する前に具体例で確認する。外部への副作用を差し替えても、戻り値・エラー・必要な状態変化を確認する。
実装と同じ計算式をテスト側にも書くと、式の間違いまで複製して緑になることがある。まず仕様から入力と期待値を具体的に決め、アサーションで照合する。たとえば「小計が3,000円以上なら送料無料」なら2,999円・3,000円・3,001円を用意し、送料をそれぞれ決める。振る舞いが同じリファクタリングでは、主要な期待値を変えずに確かめられるテストが役立つ。実装詳細の検証も、重複送信の防止など必要な契約なら有効だが、単に今のコードを固定するためには増やさない。網羅率が高くても期待値の正しさまでは保証しない。
トレードオフ
- 公開された操作の結果を確認する
- 得るもの:内部を整理しても主要な期待値を保ちやすい
- 払うもの:内部の不要な処理や性能劣化は別の確認が必要な場合がある
- 必要な依存先への呼び出しも確認する
- 得るもの:二重送信など、呼び出し自体の契約を守れる
- 払うもの:契約でない内部の順序や回数まで固定すると変更に弱くなる
さらに学ぶ
チェック
「小計3,000円以上で送料無料」を実装した。境目の誤りを最も直接見つける期待値は?
- 内部の補助関数が今と同じ名前で呼ばれる
- 小計3,000円の送料が0円になる
- テストも実装と同じ比較式で送料を計算する
解答と解説
小計3,000円の送料が0円になる
3,000円ちょうどの期待値は、以上とより大きいの取り違えを検出する。補助関数の名前は送料の仕様を確認しない。同じ比較式を複製すると、同じ境界の誤りをテストにも持ち込むことがある。