C0カバレッジ100%のためのDSL
Railsでちゃんとした製品を作るとしたら自動テストは欠かせません。型チェックのある他の言語でもテストケースは書くべきですので、言語としての型チェックのないRubyでそれをしないでいいはずありません。
ただし単にテストをするべきと言っても、バグを減らすためにはコードのカバレッジが重要です。RubyにはRCovというカバレッジ計測ツールがあります。「メンテナンスは考えないでいいからとにかく実装を!」(と言っても結局はメンテすることが多いはずだけど)というプロジェクト以外は、必須のツールです。
で、このRCovですが、C0、C1、C2、C3kとあるモジュールのテストカバレッジ(テスト網羅性 http://itpro.nikkeibp.co.jp/article/COLUMN/20071026/285596/?P=3)のうち C0をサポートしているだけですのでご注意を。
僕がテストを書くタイミングは以下の4つにするように心がけています
アプリケーション、プラグイン、gemなどのコードを書く前
これは経験的なもので、後からテストを書くのがしんどいからです。プロジェクトによってはテストを書くフェーズを実装の後にした方が管理しやすいからということで、実装と単体テストを分ける場合もありますが、ここは譲れないです。最悪 単体テスト--> 実装、という流れにするくらいの気持ちで交渉します。そんなことにはなったことないですけど。
バグが見つかったとき
最近参加したプロジェクトではtracでバグなど管理していますが、チケットのないコミットを原則禁止しています。バグがチケットで管理されていれば、大抵それに対する修正も発生するはずですので、それをコミットしますが、その際にちゃんと直したことが分かるようなテストを記述します。これを書いておくと、もしかして修正ミス?っていう心配が減ります。
心配になったとき
基本チケットのないコミットは禁止したいので、テストといえどもむやみにコミットしたくないです。なぜそのテストが必要になったのかが分からなくなるので。しかし、無性に心配になってしまうことはあります。そういうときはその心配をチームで共有するためにもチケットに上げておくのがいいと思います。で、そのチケットにテストをコミットしておくと。
rcovで100%に達していないとき
100%に達することはバグを減らすための手段でしかありませんが、100%かどうかというのはバグを発見する上でも非常に重要です。なので、100%に達していないコードを見かけたらテストを追加するようにしています。
で、DSLですよ
ここからが本題なのですが100%を達成させるための一番の近道はできるだけテスト対象となるコードを書かないことです。
テスト対象が少なければ必然的にテストコードも少なくなります。
例えばバリデーション。validateメソッドをオーバーライドしてバリデーションを記述することも必要な場合もありますが、クラスメソッドのvalidates_xxxxを使えば、クラス定義時にそのメソッド呼び出しは実行されるので、カバレッジ100%を達成するためのテスト対象を減らすことができます。
あとよくあるのが、複雑なSELECT文の組み立て。これもDSLちっくにSELECT文を組み立てるクラスをアーキテクト(じゃなかったらチームに一人はいるであろう詳しい人)が作ってあげれば、アプリ開発者がそれをテスト対象外にすることができるはずです。もちろん、アーキテクトは自分の欠いた部分のテストを書きますし、またアプリ開発者もそのクラスを使う部分はきっとコードを書くはずなので、使う部分としてのテストは必要になると思いますが。