第6回「Groovyイン・アクション読書会」IN 関西 : ATND で LT 枠をいただいたので、「契約プログラミング」という題で、GContracts の紹介をしました。*1
セッション資料はこちら 契約プログラミング
GContracts は以前少しだけ取り上げました*2が、バージョンも 1.2.1 に上がり、1.2 系から機能が結構追加されています。
GContracts 1.2.0 Released! | Blog
Interface にも Contracts を指定出来るようになったのが大きいかなと思います。
セッション資料には記載していませんが、単体テスト用のモックと契約プログラミングの相性って結構良いのではと思っています。
UnitTest でよくモックを利用しますが、そのモックが仕様通りの動作を保障しているのかはテストしませんよね?
例えばこんな Interface があって、
interface I金額計算 { int 絶対に0以上の値を返す(int 単価, int 数量); }
これの実装クラスのテストでは、仕様を満たすようなテストを書くでしょう。
class 金額計算Impl implements I金額計算 { int 絶対に0以上の値を返す(int 単価, int 数量) { assert 単価 > 0; assert 数量 >= 0; return 単価 * 数量; } } class 金額計算テスト { public void 単価が0未満() { ... } public void 単価が0() { ... } public void 数量が0未満() { ... } public void 単価1数量0() { ... } ... }
ただ、I金額計算 を利用しているクラス、メソッドのテストで I金額計算 をモック化して利用する場合に、そのモックが I金額計算 の仕様を満たしている事の保障は結構難しい問題だと思います。
class 業務ロジック { void 業務処理(..., I金額計算 instance) { ... int 金額 = instance.絶対に0以上の値を返す(...); ... } } class 業務ロジックテスト { public void 業務処理テスト() { 業務ロジック instance = new 業務ロジック(); I金額計算 mock = ... // モックを生成(このモックは仕様を満たしている?) instance.業務処理(..., mock); } }
※今回の例では簡単だと思いますが…
契約プログラミングを利用すると、こういう所で効いてくるんじゃないかな〜と個人的に思ってます。
ただ、GContracts は紹介しただけで殆ど触っていません。そこで、契約プログラミングの例として慣れている .NET でちょっとしたコードや、IDE(Visual Studio) でのサポートを紹介しました。
契約プログラミング:Contracts - Microsoft Research
テストツール:Pex, Automated White box Testing for .NET - Microsoft Research
まだまだ使いこなせていませんが、Pex と Code Contracts の組み合わせはかなり強力そうです。試すだけなら、こちらのサイトで試せますので是非一度お試しを!
Code Contracts @ rise4fun from Microsoft
Pex for fun - from Microsoft Research
※Pex は Coding Duel という方式で問題を解いていく事が出来ます、これが結構面白い!