TDD Advent Celndar 2012 12日目の記事になります。
11日目は @bash0C7 さんの
ハイプレッシャーを克服するためのテスト駆動開発の重要な「二歩目」#TddAdventJp - koeだめ
でした。 プ、プレッシャー……、読んでて、TDDとっかかりの頃の「どーすればいいんだ」的な気持ちを思い出しました。初心忘れずでいたいよね、ってことで、12日目、行きましょう。
TDDは新規開発だけの手法?
いえいえ、リファクタリングにも使えます。
それだけ?
いえいえ、私は、虫退治、ことバグ取り、でも有効な手段だと思っています。
アプリケーション稼働後や総合テスト中にバグ発覚!こんなときだってTDDで退治しちゃえば良いんです。
てなお話を。
手順は次の通り。
- バグが発生するまでに呼び出されていたクラスを列挙する。
- それらのクラス個々に対して「バグ発生時のデータと条件下で本来どうあるべきだったのか」テストを追加してレッドとなるテストがあることを確認する。
- 追加した全てのテストがグリーンとなるまで修正作業を行う。
- 既存すべてのテストがグリーンとなることを確認する。
ポイントは2。バグが発生するまでに、実行されていたクラスメソッドをさかのぼり、「このクラスメソッドではこんなデータや条件の場合に、こうあるべきだった」テストを追加していく下りです。
つまり、テストコードでバグ発生当時を再現していく、ってことですね。もしかしたら、その想定データや条件はすでにテストにあったりするかもしれません。そうしたら、ここはとりあえずテストコードを書く必要はないな、となるでしょう。現場によっては、再現作業の中で、仕様に問題があることが判ったりして、きちっとテストコードを書いていると何かと助かることもあったりします。
そして追加したテストの中に、レッドとなるテストが存在するはずです。
そのテストの対象メソッドにバグが隠れている可能性が高いわけですから、実装コードの修正箇所がしぼられてきます。
ここまでの間に、実装は全く手を付けないで、テストコードだけに着手する、これが大事です。
実装コードに手を付けるのは、レッドとなるテストをすべて洗い出してから、にします。
特定と修正個所が確定したら、ここから実装コードを修正して、グリーンになれば勝利……のはずですが、そのグリーン、追加したテストだけじゃ意味がない。つまり、4.が重要になります。
修正したことによって、既存の「こうなるべき」ところに影響が出ているかもしれません。
今回追加したテストも含め、既存のテスト全てがグリーンとなることを必ず確認することが大事です。
つまり、TDDは新規開発、リファクタリングにのみならず、バグと問題のあぶり出し、修正後の動作担保までとってくれる、現場には有難い手法でもあるのですね。
以下、オマケ話。
私は近年Javaでプログラミングすることが多いので、テストにJunitを使っています。
規模の大きなアプリケーションだと、たくさんのパッケージ、クラスになってきてそれらのテストも膨大です。一連のこの機能だけの結合テストをしたい、なんて時には全部流すと時間がもったいない。
そこでTestSuiteクラス、実行したいテストクラスだけをまとめておける機能が備わっているクラスを使って、テストアプリケーションを作って実行していくことで効率をあげています。
といっても、Mainメソッドの中に対象となるテストクラスの名前がずらーっと列挙されてて、最後に1行テスト実行メソッド書く、という構成の、作業のたびに作り直しのメンドクサイものでしたけれど。
ところが、Junit4では列挙しなくてはならなかったTestSuiteの対象クラスをアノテーションにまとめられるようになりました。アノテーションというのはオブジェクト定義の時に付与できるパラメータのようなものなのですが、これを使うことでMainメソッドの中のコードを触る必要がなくなります。
1: @RunWith(Suite.class)
2: @SuiteClasses({ AxxxTest.class, BxxxTest.class, CxxxTest.class, DxxxTest.class })
3: public class TestSuiteRunner {
4: public static void main(String[] args) {
5: JUnitCore.main(AllTests.class.getName());
6: }
7: }
サンプルの2行目の@マークのある1行に、あちこちのパッケージに散らばってしまったテストクラスをまとめて、その行だけ履歴管理できれば良いのですから、とっても便利。
というわけで、オマケでしたv
次はposaunehmさんです。