2011年6月11日土曜日

なぜ UnitTestが生産性を上げるか

前回、UnitTest の必要性について書き始めて、どうやらコーディングの生産性向上らしいってとこまで来た。今回はその続き。

====
UnitTest はコーディングの生産性を高める。

・・・というのは少し大雑把で、より正確には、高い生産性を得るために最も重要な条件の成立に、UnitTest が不可欠であると言う事になる。

で、その条件とはすなわち「内部品質が高い」と言う事である。

この内部品質を高める事により、「ソースを読む」、「書き足す」、「書き直す」、「間違いを探す」と言った、コーディングの大部分を構成する作業に要する時間を大幅に削減できる。内部品質が高まるほど、コーディングの所要時間が下がり、生産性が上がってくる。

では、なぜ UnitTest が内部品質の向上に寄与するのか?

これは、UnitTest が内部品質向上作業の生産性を高めるからなのだけど、この「内部品質向上作業」とは、ザックリ言うとリファクタリングの事である。

このリファクタリングを徹底的に(Mercilessly)に行う事により、高度な生産性を実現できるような、高いㇾベルの内部品質に初めて到達できる。ここで UnitTest は、リファクタリング作業それ自体の生産性を高めるために(同時にリスクを下げるために)利用される。

これ以上の説明は不要な気がしないでもないが、なぜ UnitTest によってリファクタリング作業の効率性が高まるかというと、コード修正による「意図せざる事象」をもっとも効率よく検出できるからと言える。
前にも書いたが、UnitTest とは「doing the right things(正しい動作をしている事)」ではなく、「"doing things right"(正しく動作している事)」を検証するものである。ここで「正しく」とは、「意図した通り」という意味なわけで、つまり UnitTestとは「意図せざる事象」を発見する仕組みという事になる。

リファクタリングという作業は、極論すれば仕様なんて知らなくても良いとうホワイトボックスの中身だけに着目した作業と言える。また、プログラムの成長に伴い、随時(常時)、実施していくものなので、必然的に反復作業となる。

従って、外観の振る舞いを変えずにソースコード修正を繰り返すリファクタリングという作業に当たっては、自動化ホワイトボックステストである UnitTest が最適なプラクティスということになる。FunctionalTest でも結果的に「意図しない動作」を検出できないでもないが、直接性において UnitTest に比べて劣る。

ちなみに、そもそも JUnit を用いた UnitTest が広く一般に認知されたのは、ファウラーのリファクタ本で紹介されたのが契機だったりするので、歴史的にも UnitTest は リファクタリング と密接に関連付けられたプラクティスだと言える。(JUnit を使う事が UnitTest であるとは必ずしも言えないが)

以上、コーディング生産性向上と UnitTest の関係についてだいたい説明したが、振り返ってまとめると、以下のようになる。
UnitTest を充分書く

リファクタリングの生産性が高まる

内部品質が向上する

短い時間で正しいコーディングが簡単にできるようになってくる


これは、以下のように逆に書くこともできる

UnitTest を書かない

リファクタリングできない

内部品質が低下する

頭をかきむしりながら長時間かけてるのにバギーなコード


====
実際の現場では、逆に書いた版のプロジェクトが、未だに多いんだよなあ。

UnitTest をしないからリファクタできないパターンと、リファクタリングをしない(或いはそもそも知らない)から、UnitTestの必要性が分からないってパターンの両方考えられるが、どっちにしても低レベルすぎる。

といったわけで、内部品質の劣悪なソースコードと UnitTest の不履行との間には高い相関があるわけだけど、内部品質だけじゃなく外部品質、つまりバグやらパフォーマンス劣化やらにも巡り巡って因果関係が及んでいたりする。
そのうちこれも書こうと思う。

0 件のコメント:

コメントを投稿