テストが守るのは文法ではなく約束。build も run も通るのに、約束が破られた瞬間に「どこが」を名指しで教えてくれる。
約束とは「この関数や API は、この入力に対してこう振る舞う」という取り決めのこと。たとえば「200 なら body を返す」「503 が続いたらリトライする」「全ての行に LOAD TS が付く」。
コードのミスは 2 種類に分かれ、守る道具が違う。
| ミスの種類 | 例 | 咎める道具 |
|---|---|---|
| 文法のミス | 型が合わない・未使用変数 | go build / go vet |
| 約束のミス | 動くけど結果がおかしい | テストだけ |
テストは咎めるだけでなく、何が原因かを瞬時に出してくれるので、ドキュメントの役割も持つ。
「事前に想定できたか」で 3 つに読み分ける。テストに書けるのは前の 2 つだけ。
| 区分 | 例 | テストに書けるか |
|---|---|---|
| 正常系 | 200 なら body を返す | 書く |
| 異常系 | 503 が続く。想定したエラーが出るか、リトライできるか | 書く |
| 想定外 | まだ見たことがない入力 | 書けない。本番で見つけ次第ハンドリングし、異常系テストに昇格する |
エラーハンドリングは想定外の入力への振る舞いを決める別の道具で、テストの代わりにはならない。
テスト名は 2 つの型のどちらかに収める。
It("{入力や状況} なら {戻り値・副作用・呼ばれないもの}", func() { ... })
It("{出力の対象} は {常に成り立つこと}", func() { ... })
// 条件が思いつかないとき: 何を渡すと違う結果になるか、を先に列挙する
// 結果が思いつかないとき: Expect に何を載せるか、を先に決める
テストは書こうと思えば無限。異常系は特に。1 本書くたびに次の 4 つで足を止める。
書けるのは正常系と異常系だけで、想定外は本番で拾って異常系に昇格させる。書く量は 4 つの問いで止める。