プラグマティックTDDとはなにか?

by JOSEPH YODER on JANUARY 11, 2012

by Joseph Yoder & Rebecca Wirfs-Brock

僕らがプラグマティックTDDという言葉を使うわけ

プラグマティック・テスト駆動開発(TDD)は、大局的な見方を大事にしながらチームのソフトウェア開発プラクティスにテスティングをどう使えば役に立つか考えるという、テスティングのアプローチです。
開発者はユニットテストをたくさん書くべしと言ったりはしないんです。そのかわり、より高い品質にたどりつけるよう、テスティングの戦略を見つけないといけません。
テスティングを自分の状況でどう利用するのがベストか、メンバーやソフトウェアの種類に応じて、決断する必要があるんですよ。

よくあるTDDは、開発者がユニットテストを多数書くことになっていますが、個々のユニットテストに価値があるかどうかはわかりません。僕たちのオススメはこうです。最高のレバレッジをきかせられるテスティング戦略を適用せよ。たとえば、ユニットテストたくさんよりも、ユーザーレベルの受入テストを適切に定義するほうが価値が高いことが多いですね。テスティングが開発を駆動するのです(ただしそれ以外のコーディングやデザインのプラクティスを捨てていいってわけでもないですよ)。いつでもどこでも使える万能のテスティング戦略なんてのはないんです。

TDDを組織導入しない理由でよくあるのが、次のような誤解です。いわく必ずテストを最初に書かなければいけない、プロダクションコードを1行も書く前にテストを書くのだ、テストとコードは小さなインクリメントで同時に書け、ってやつですね。僕たちは思うんですが、TDDってむしろ自分のソフトウェアと自分の要求をどう確認(validate)するのがベストかじっくり考えようという話なんです。テスティングと確認(validation)がセットになって、開発プロセスを駆動するべきなんですよ(なんで僕たちはテスト駆動が大好きです)。テスティングは、ユニットテストをいっぱい書くだけの話じゃありません。

テスティングの「リズム」の違いとは何か

僕たちはテスティングは大事なもので、日々のプログラミングの中の欠かせない部分だと思っています。だけど、コードを書くときは常に小さなサイクルでテストも一緒に育てるのがいいとも限りません。先にアウトライン的なテストのシナリオだけ書いて、そのテストシナリオをコーディングのガイドとするやり方のほうがうまくいくという人もいます。そこそこ実装ができて想定シナリオが動かせるようになったら、そこでテストを実際に実装し、順次バグをつぶしていきます。テスティングなしで何百行もコードを書くというのでさえなければ、こういうやりかたもアリだと僕らは思ってます(なんにせよ、どのやり方がいいという話ではありません)。

どんなテスティングプラクティスを考えるのか?

TDD上手になるのはたいへんです。テストスイートを自動化し、リファクタリングと書き直しでテストから重複を取り除き、例外ケースをテストしと、キリがありませんね。それに受入テスト、スモークテスト、結合、パフォーマンスや負荷テストもインクリメンタルな開発に役立つものです。こうしたテスティングが手に負えないなあと感じましたか?よし、それではプラクティカルになりましょう!テスティングはテスティングのためにあらず、です。あなたが書くテストは、あなたにレバレッジを与えるのです。コードを変えたり育てたりするのにより自信が持てるようになり、システムが要求に合っているか確認することもできます。だからこそ、何をテストし何をテストしないのか、どこまでテストするのか、それを知るのが大事なのです。

それでどこから始めればいいのか?

チームにテスティングの文化を作るのが重要です。同じ手法やツールをチームに広めましょう。いろいろなやり方を試してみて、グループとして得たものを確認しましょう(ふりかえりをするのがいいです)。新しいプロジェクトを始めるところなのであれば、既存コードがあるときとはアプローチががらっと変わるかもしれませんね。圧倒されないようにしてください。フォーカスしたいエリアを決めましょう。たとえば、新しい機能のユニットテストを書くのは簡単です。ですが既存コードに、バグが多いとか変更したいとかで、テストを書きたいときもあります。こちらのほうが難しいので、先に結合テストを自動化するのにフォーカスするほうがいいかもしれません(そすればビルドとデプロイのプロセスが整理できます)。とにかく、どこに投資したいかにかかっているわけです。始めはほどほどに、テスティングプラクティスを育てつつ、テスティングの手間と利点を測定しましょう。当たり前かもしれませんが、一番大切なのは実際に始めて、テスティングを開発プロセスの欠かせない一部にしていくことです。