TDDは設計手法
TDDの話をすると「テストを先に書くやつでしょ」で止まっちゃうことがあるけど、本来は設計手法。テストを書くことで設計と検証のループを早く回す、それが本質。
AIが出てきて「コード書くの速くなったからテストいらなくね?」みたいな空気もあるけど、むしろ逆だと思っている。AIがコードを書いてくれるからこそ、自分でハンドルできる最小単位で作って、テストでアップデートしていく方がいい。
テストがあれば設計は自由になる
テストがあると何がいいかというと、設計を後から変えられる。リファクタリングしても壊れてないことがすぐわかる。新しい機能を作るときにデグレしたかを検知できる。
逆にテストがないと、「動いてるから触らない」コードが増えていく。早く実装できるからってロジックにテスト書いてこないのは、そのタイミングでは問題なくても、後から新しく作るときに開発体験が悪くなる。
最初から網羅しなくていい、小さく育てればいい
TDDで一番大事なのは「最初からテストケースを網羅しようとしない」こと。
やることはシンプルで、まず「これができたらいいよね」っていう最小のテストを1つ書く。それが通る最小の実装を書く。次の要求が出てきたら、同じテストを育てる。「この場合どうなる?」が見えてきたらテストを分ける。それだけ。
1. 最小のテストを書く
→ "発送依頼を取得して処理する"
2. テストが通る最小の実装を書く
3. 次の要求が出てきたら、同じテストを育てる
→ FTPアップロードの処理を追加
4. 「この場合どうなる?」が出てきたら分ける
→ "FTPアップロードに失敗したらエラーを返す"
テストの側だけゴールを書いて、中身は一気に書かなくてもいい。少しずつ足して、確認して、通して、重複をリファクタリングしていく。「usecaseを実行したら成功する」くらいのテストから始めてもOK。
綺麗なテストが最初から書けている必要もない。テストを残すか残さないかは、残して価値があるかを判断すればいいだけ。TDDにおいてテストはあくまで確認するツールで、早くフィードバックを得て実装を進めていくためのもの。
「わからないまま小さく進めて、わかったら直す」のがTDDの正しい姿だと思っている。
とはいえ、全部にテストを書く必要はない。手動確認でいいところはあるし、大事なところだけ守れていればいい。やり方は自由で、とにかく目的に向かって最短で検証していけばいい。そのためにTDDで設計と効果検証のループを早く回す。
他の人とコードを書くときはテストを軸にする
ペアプロでもレビューでも、実装の書き方で意見が分かれる場面がある。「こう実装した方がいい」「こっちの方が綺麗」みたいな話。そこに深入りするのはもったいない。
テストを軸にすれば、そこで止まらずに済む。先にテストを書くことで小さいゴールが確定する。「そこまでできたらOKだよね」ってなる。実装をどうするかじゃなくて、どういう振る舞いをさせるかで話せる。
もう1つ大事なのは、動いているものに対してフィードバックすること。パフォーマンスとか、どこでどう呼ぶかみたいな話は、実装中に考えすぎなくていい。まずテスト書いて動くものを作って、それから検証すればいい。動いているものに対してのフィードバックの方が、双方にとって摩擦が少ない。
テストがあるからこそ「こうリファクタリングしたらいいんじゃない?」って提案して、テスト通ったらOK。それでも納得できないならそこで議論すればいい。結果が見えない話に時間をかけるより、動かして確かめる方が早い。
ペアプロにしろレビューにしろ、一緒にやる人とフォーカスすべきは一緒にやれること。手を動かさない議論は最小限にして、テストと実装でフィードバックを得て、コードを洗練させていく。
結局自分が言いたいのは「遠回りしたくない、小さく作って早く価値を出したい、テストがあれば設計は後からどうにでもなる」ということ。AIがあってもなくても、この軸は変わらない。
この「小さく作って早く確認する」という考え方自体については別の記事でもう少し掘り下げて書いた。TDDはその具体的な手段の一つ。