shouldaでcontextをネストしてみる

Rubyのテストフレームワークのひとつ Shoulda を使ってみました。

Railsならば素直にRspecなんでしょうが、せっかくPadrinoを使っているので。Padrino自体もテストにShouldaを採用しているようです。PadrinoといえばRake 0.9.0でテスト動かないよというIssueがrvmのせいだと決めつけてrvm開発者に反論され、うやむやにcloseされているんですがどうなんですかね。ちなみにRakeを0.8.7にバージョンを落としたら問題なくテスト動きました。

Shouldaではcontextという単位でテストを記述していきます。そしてcontextはネスト(入れ子に)できます。仕様を正確に記述するためには、ネストされた各contextがどういう順序で実行されていくのかを把握しく必要があります。そのため、次のようなサンプルを実行してみました。

outer contextの中にinner context 1と2 がネストされています。そして、それぞれのcontextにsetupとteardownがあります。実行順を把握するため各所でpをよんでいます。これを実行すると、次のような出力が得られます。

テスト自体はネストされたcontxtの1、2、そして外側のcontextの順で動作するようです。そして、各contextの前後でsetupおよびteardownがよばれています。外側のcontextに属したsetup、teardownはネストされたcontextの前後にも必ずよばれ、計3回よばれることとなります。これを把握しておけば、テストの一連の流れにおいて共通部分をどのようにまとめあげ、contextをネストすればよいかわかりますね。
さて、前述のサンプルテストコードでは、外側のネストされたcontextの後のshould文をコメントアウトしてしまっています。これをアンコメントした状態で実行すると次のような出力がえられます。

外側のcontextのshould文ついては、後のものだけが実行され、先ほどの "outer context 1 test" は実行されていないようです。これについては、contextをもう一段ネストしてやって回避するなどの対策が必要となりそう。あるいは、テストコードに列挙された仕様を、テストの流れに沿ってDRY UPしていく過程では今回のサンプルのようにネストされたcontextの前後にshould文が生じることはないのかもしれません。
正しく、そして美しいコードは、仕様を正確に反映したテストからうまれます。偉そうに言い切ってみましたが、恥ずかしながらテストを書いてみたのは今回が初めてです。ごめんなさい。でも、きっとそうです。仕様をテストコードに落とすという行為は考えを整理することにもつながりますし、開発には欠かせないステップだと、今は思います。テスト書こう。テスト書こう。大事なので2回いいました。