カテゴリー:
Rails
タグ:
 テスト

このエントリーをはてなブックマークに追加
更新日時:
2015年04月23日(木)
作成日時:
2015年04月23日(木)

前の記事 / 次の記事

Railsのテストについて考えまくった結果
一定の結論に達した気がした(たぶん気のせい)のでメモ。

全ての要件を漏れなくテストできればそれがいいに決まってる。
でも無理。

っていうかやる時間があったとしてもそれは果たして意味があるのか。
勝手に天から降りてくるならいいけど。

で、落としどころを探る。

フレームワークはRspecを使う。

大前提としてロジックが介在しないヶ所はテストしない。
例えばCSSが仕様通り書かれているかみたいのはテストしない。
ていうかロジックがないヶ所のテストとかただのコンペアだから不毛。

コンペアが不毛っていうことじゃなくて、
コンペアするために正解である比較対象を用意しなきゃいけないけど
その用意した比較対象が本当に正しいかどうかってどこで判定するんだよ
っていうかそういうところの間違ってたらもう諦めるしかない。

テストの方針としてはバグったらアプリケーションが破綻するヶ所と、
目視で確認するのは面倒なヶ所について「のみ」テストする。

「のみ」っていうのはたぶん重要で、
ついでにこのテストも書いておこうみたいのは駄目。
それやってるとどんどん膨らむ。

アプリケーションが破綻するヶ所、
っていうのは例えば何かの投稿フォームがあったとして、
投稿ができるかどうか、とか投稿した結果仕様通りレコードが作成されているかとか。

アプリケーションが破綻しないヶ所、
っていうのは例えばタイトルが間違ってないかとか、
ユーザーの名前が表示されてるかどうかとか。

そういうのは表示されてなくても直せるし、すぐ気付くはずなのでテストしなくていい。
逆に言うとバグったらすぐ直せないか、バグったら戻し不可能みたいなヶ所は徹底的にテストする。

あと、目視で確認するのは面倒なヶ所、
っていうのは、テストを書かないヶ所であっても、
テストをしないのではなく、目視で確認する。

従って目視の確認が必要だけど時間が超かかるようなヶ所は
capybaraとか使ってプログラムにやらせる。

次にテストの切り分け。

コントローラのテストは省かれがちだけど省かない。
コントローラには主に認証というかrole管理というか、
条件によってページを見せたり見せなかったりする部分のテストを行う。

これはcapybaraで代替する場合も多いと思うけど、
capybaraで書くより低いコストで書けるのでコントローラーのテストにやらせる。

また、インスタンス変数の割り当てはコントローラーの役割だけど、
これはテストしない、っていうかインスタンス変数割り当てられてなかったら
明らかにビューの表示がバグってるはずなのでバグ見逃しとか基本的にないはず。

あとコントローラーからモデルのメソッドをキックする場合は、@book.save とか。
単純なケースなら it { is_expected.to change(Book, :count).by 1 } とか
やって確認してもいいと思うけど、基本的にはモデルのメソッドをキックした結果
想定した結果になっているかというのはテストしない。それはモデルの責務だから。

なので、
スタブやモックを使ってあるメソッドをキックしているかどうかということだけど確認する。
キックした結果によって処理を振り分ける場合は and_return とかでシミュレートする。

ビューのテストは書かない。一切書かない。
但し、必要な箇所はcapybaraで代替する。

ビューのテストというのは、もしビューを高度に抽象化して書けていたら、
ビューはビューでテストした方がいいのだと思う。

でもビューの抽象化ってたぶん可読性を保ったまま抽象化するのは激難だから、
激難である以上、頑張って抽象化する必要はないのではと思う。

それに大抵の場合Railsのビューというのはある程度コントローラーに依存した形に
なるのが必然だと思うので、ビューを単独でテストするっていうのは現実的じゃない。
と思う。

で、capybaraで代替するとしてcapybaraには何をやらせるのか。
postやpachのトリガーになる部分とJavaScript。

ただ、前提としてJavaScriptは極力書かない。
どうしても書いてしまった場合は、capybaraを通してテストする。
バリバリJavaScript使う場合は別途JavaScript用のテストフレームワークを
使った方が良いのではないかと。

モデルのテストは基本全て書く、
が特にバリデーションとフックについては漏れがないように注意して書く。
ここがしっかりしてれば他のどこかでバグってもデータの整合性は破壊されない、
からこの部分が最重要。

な感じ。で今のところ思っている。

あとテストは可読性が上がるならDRYにしない。
可読性の低いテストは後で見て何をテストしてるのかもはや意味不明になって
テストの存在価値がないので可読性が最優先。
少なくとも実際のコード以上に分かりやすくなければならない、と思う。

頑張って強引な処理をしているコードでも
テストはそれが何をしているのが簡潔に書かれていてこそだと思う。
逆にテストが簡潔にかかれていれば実際のコードは多少無茶をしてもいいんじゃないかと。

寝る。