プログラマでありたい

おっさんになっても、プログラマでありつづけたい

プログラム言語はユニットテスト可能かどうかの観点で考えてみよう

 面白いエントリーがありました。
Java EEや.NETはCOBOLやVB6よりも本当に生産性が高いか?


 私も正直、オブジェクト指向だから生産性が高いとか、最新のフレームワークを使えばハッピーになれると言った言説には疑問があります。ということで上記エントリーについては基本的には同意なのですが、そこに至った過程が違います。


 私にとって大切なのは、ユニットテストが出来るかどうか。また、ユニットテストを継続的に自動実行を出来る環境があるかどうかです。この2点です。ユニットテストのメリットは、色々なところで語られているので詳しくは書きませんが、次の3点に集約できるかと思います。
・テストの再現性がある。(退行テストが用意)
・プログラム変更の予期せぬ影響が発見される可能性が高い
・プログラムの構造が洗練され、ソースが綺麗になる


 1番目の再現性ですが、一度テストプログラムを書いておけば何度でも実行できます。人間がテストすると、仮に1ケース5分かかるとすると20ケースで100分です。もう1回テストしようとすると、また100分掛かります。それならば、最初に1ケースに10分掛けてでもテストケースを書いておけば、今後のテストの実施は数秒で終わります。開発フェーズより運用フェーズの方が長いのが、ソフトウェアのライフサイクルです。その間に何回の改修が入るかと考えれば、初期に工数を掛けてでもテストを実装するメリットがあると思います。
 次に予期せぬ影響の発見ですが、前述の通りユニットテストを書いておけば全件の再テストは容易です。そうなると、一つのメソッドを変更した場合、別のメソッドでエラーが出ているということも出てきます。開発者自身が気がついていない関連性が発見できるのです。もちろんユニットテストのテスト内容によっては発見出来ないこともありますし、そもそも密結合の作り方が悪いというのもあるかもしれません。ただユニットテストを実施していなければ、気付きもしなかったものが発見出来る可能性は高くなります。
 最後に綺麗なソースについてですが、これについては?となる人が多いと思います。ただ実際にテストコードを書いてみればすぐに気が付くと思います。例えば一つのメソッドに複数の機能や、IF文ループのオンパレードであれば、テストコードを書くのは困難です。IF文5個のメソッドに条件網羅しようとすると32個のテストコードが必要になります。これに対し、1メソッド1IF文ならば、テストコードは10個です。(別に1メソッドに1IF文とか言っている訳ではないですよ。)
 人間、自分でやらないといけないと思ったら、出来るだけ楽に出来るように努力するものです。そうなると、自分でコードとテストコードを書くとなると、どうするか?IF文のオンパレードのメソッドと沢山のテストコードを書くくらいより、小さなメソッドとシンプルなテストコードを書くようになります。色々な人にテストコードを書いて貰いましたが、だいたいの場合は同じように適切なメソッド分割がなされるようになってきます。
※そういった意味で、プログラムの詳細設計する人と実際にコーディングする人を分けるのは駄目駄目と解ると思います。


 ユニットテストのメリットは上記の通りなのですが、ではどんなフレームワーク、プログラム言語だとユニットテストは書けるのでしょうか?結論から言うと殆どの言語で書けます。(COBOLは除きます。)
 ただし、継続的な実行が容易かという観点では、プログラム言語だけではなくフレームワークの助けを得ないと難しいでしょう。その点、最近のフレームワークについてはテストのことを考慮して作られているので、かなり楽です。またオブジェクト指向か否かも、テストのし易さを考えていけば自然に辿り着けます。ということで、言語の優劣やフレームワーク論争をする人たちには、テストコード書いてみろと言ってみましょう。重要なのは、テスタブルかどうか。それだけです。
(別に使い捨てコードにテスト書けとは言いませんけどね。)