Rails標準のテストとRSpecのテストの種類の対応

ちょっと整理してみた。
RSpecは本当はRSpec on Railsと書くべきかもしれないけど冗長なのでRSpecで行きます。

対応表

対象 標準 RSpec
モデル Unit Test Model Examples
コントローラ Functional Test Controller Examples
ビュー View Examples
ヘルパー なし Helper Examples
インテグレーションテスト Integration Test User Stories

RSpecへ移行した観点からの所見

狭い見識からちょっとした雑感をば。

コントローラのテストが書きやすくなった

Railsの機能テスト(Functional Test)ではコントローラとビューのテストをいっしょくたに扱っていたが、RSpecでは別々になっている。

そのためコントローラのテストが書きやすい。
データベースからの値の取得やセッションの状態の確認、どのテンプレートをレンダリングしているか、httpのレスポンスの結果は何か、などコントローラの仕事だけにフォーカスしてテスト(「Example」と呼ぶべきなんだろうけどまだなじみがないので「テスト」で)が書けるので、ビューテンプレート側での変更などを気にする必要がなくなった。

デザイン変更で機能テスト失敗するようになりましたとか言う凹む状況から解放された。

ビューのテストはいらない子になった

同じようにビューのテストでもビューテンプレートとしての役割だけに集中したテストが独立した形で書けるようになっている。

が、一方でコントローラとビューの連携が正しく働いているかということがテストできなくなった。(ビューが要求している変数をコントローラがちゃんとアサインしているかなど)
つまりコントローラのテストとビューのテストが単体でそれぞれパスしていても、実際動いたときにきちんと動くかどうかはわからなくなった。

この問題に関してはビューのテストをストーリーテスト(User Stories)で対応することが推奨されている。
正しい気がする。

というわけなのでビューのテストは書かないで必要ならばインテグレーションテストのレイヤーに任せようと思っている。
単体での動作を確実に確認しておきたいややこしい処理はモデルとかコントローラにだいたい集まってるはずだしね。

ビューのテストでCSSセレクタが使える

assert_tagでタグの指定をするのはけっこうめんどうだったが、RSpecのhave_tagマッチャではCSSセレクタが使えるのでそれなりに楽になった。

ビューのテストは今のところ書く気がないがストーリーテストでもhave_tagマッチャは使える。

ヘルパーのテストをサポート

Rails標準ではヘルパーを扱うテストはなかったが、RSpecではサポートしている。

従来のRailsでもヘルパーのテストを書く方法は紹介されていたりする(Railsレシピなど参照)が、そういう手法のノウハウがなくても最初から書けるようになっているというのはよいことだ。

ビューの気になる部分をヘルパーに切り出してテスト対象にするとかもありかも。

インテグレーションテスト

これはもともと書いてなかったのでよくわからない。

しかしRSpecのUser Stiriesはメンテするのがけっこうめんどくさい気がしている。
テキストファイルに簡易なユースケースっぽいScenarioを書いてそれに沿ったStepを書くという形式なのだが、Scenarioの文言を変更するとStepの方も修正しないといかんというのがイマイチ微妙(文言をあわせないといかんのです)・・・
慣れればそうでもないんだろうか。

簡単に書けないのならSeleniumとかに走った方が幸せになれるかもしれないな。Selenium on Railsとかもあることだし。
ただまあSeleniumはSeleniumで実行に時間がかかるというネックを抱えているんだが。

インテグレーションテストのレベルになると何をテストして何をテストしないかの取捨選択が肝なんだろうか。

雑感はおまけ程度にするはずがなんか長くなってしまった。

参考

RSpec-1.1.3: Spec::Rails

Rubyist Magazine – スはスペックのス 【第 1 回】 RSpec の概要と、RSpec on Rails (モデル編)