| name | team-test-strategy |
| description | テストの要否と種類を判断し、testを実装するときと、testをreviewするときに使う。 |
test戦略
testは、壊れたときの損害が大きい挙動を守るために書く。数を揃えるためには書かない。
Testを書く対象
次に該当する場合だけ、testを書く。
- taskの
Acceptance(acceptance test)。
- 発見されたbugの再発防止(regression test)。
- 複雑なlogic。parser、planner、計算、優先順位づけなど、入力の組み合わせで挙動が分岐するもの。
- 並行処理と冪等性。
- 外部サービスとの境界。
- そのほか、仕様が曖昧、障害が起きた、変更が集中している、といった理由でbugが出やすいと判断した箇所。
該当しない変更には、testを追加せず、変更に合う直接的な検証(command実行、表示確認)を選ぶ。
module、class、public関数を網羅するunit test群は作らない。coverageの数値を目的にしない。既存の挙動を写しただけのtestは、いくつ増えても検証を増やさず、変更のたびに書き直す負債になる。
Testの種類
対象ごとに、次の中から必要と判断できる種類だけを実装する。
- 受け入れ条件を直接検証するblack-boxテスト。
- 境界値、不正入力、失敗、部分的失敗、再試行のテスト。
- 状態遷移と、禁止された状態遷移のテスト。
- 常に成立すべき不変条件を検証するproperty-basedテスト。
- 発見されたbugを再現するregression test。
- 外部システムとのschemaおよびcontract test。
- 冪等性、重複、順序変更、並行実行を検証するテスト。
一つの対象に7種類を揃えるという意味ではない。どれが必要かは、taskのAcceptanceと想定するリスクから決める。
根拠コメント
各testの直前に、次の5点をcommentとして書く。
- この期待結果は何を根拠に決めたか。仕様、
Acceptance、外部システムの文書、再現したbugなど。実装を動かして得た出力は根拠にならない。
- 何を実物として動かし、何をmockまたはfakeで置き換えるか。
- どの要件またはリスクを検証しているか。
- このtestが責任を持たない範囲は何か。
- どのような内部変更では、このtestは成功し続けるべきか。
5点を書けないtestは実装しない。書けないという事実が、そのtestが挙動ではなく実装を写していることの判定になる。
書いてはならないtest
- superficialなassertion。呼ばれた事実、nullでないこと、例外が出ないことだけを確認し、結果の中身を確認しない。
- mockの戻り値を確認するtest。自分で置き換えた値がそのまま返ることを確認しても、実物の挙動は何も検証されない。根拠コメントの「何を実物として動かすか」が書けない。
- 実装の内部構造を写したtest。private関数、呼び出し順、mockへの引数を固定し、挙動を変えないrefactoringで壊れる。根拠コメントの「成功し続けるべき内部変更」が書けない。
その他の注意
- mockは、置き換えが必要な外部作用に限る。
sleepとtimeoutへ依存する不安定なtestを避ける。
- 一つのtestでは一つの挙動を確認する。