railsでFactory Girlでフィクスチャなテストをしてみる

rubyにおけるテストの方法とか一切知らんので、調べてるうちに面白そうなのを見つけた。のでやってみよう。
フィクスチャという言葉の定義が自分の知ってるのとは違ってた。とにかく、ストレージにデータを保存するときのテスト手法みたいな。
true/falseを返すメソッドとか、値を返すメソッドなら簡単にテストできるが、「こんな構造のデータを保存できる」ってメソッドのテストはストレージ使わないと出来ないので、テストデータ作ったり保存したりと。
で、テストデータを用意するのだけど、それをyamlで書くのが面倒だからrubyのデータ構造で書こう、というのがFactory Girlらしい。
解説してるサイトを見ながらやってみた。ほぼそのまま。最後にリンク張っとくので、そっちを見た方が分かりやすいと思うよ!
色々と省略されてる個所があったので、補完しつつメモ。rails使いには書かなくても分かる事なんだろなー。
メモの中でコピペしまくってるのは、参考リンクの中の一番上のサイトから。
ここまで前振り。長いよ。

前準備

必要なgemをインストール。

% sudo gem install rspec-rails
% sudo gem install thoughtbot-factory_girl --source http://gems.github.com

プロジェクト作成

% rails -d mysql girl
% cd girl

別にmysqlにする必要は無い。使い慣れてるからです。むしろこれしかRDBMS知らないから。

設定

% vi config/environment.rb

30行目付近に、config.gemがどうこうとコメントアウトされてるので、追記。
テスト実行時にFactory Girlがロードされる、だそうで。

config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com"

モデル作成

参考リンクまんまで作成。

% ./script/generate model user name:string
% ./script/generate model page title:string url:string
% ./script/generate model bookmark user_id:integer page_id:integer
% vi app/models/*

app/models以下のファイルの編集内容は参考リンク参照。

rspecの雛型作成

% ./script/generate rspec

何か色々できる。

Factory Girlの設定

ここでテストデータの用意。

% vi ./spec/factories.rb

やっぱり参考リンクのコピペで。ruby分からなくても、見れば意味は分かる。

テストコード作成

% mkdir spec/models
% vi ./spec/models/user_spec.rb

はいはいコピペコピペ。
テストメソッド名が it とおもしろい。
るびまの方のサイトで解説してるけど、これはテストの内容とかタイトルとかを英語で書くと、テストの実行結果が分かりやすく出てくる。
日本語で書くこともできるが、英語前提なので、ちと無理やりになる。
テストコードは普通の英文のように書けて分かりやすく、外部の人が見ても意味が分かる。素敵。
こういうのDSLと言うんだっけ。

DBの用意

% rake db:create RAILS_ENV='test'
% rake db:migrate RAILS_ENV='test'

RAILS_ENVを付けないと、developmentで作っちゃうので注意。
テストは当然test用のDBでするので、test用で作らないとテスト出来ません。

テスト実行

% ./script/spec -fs -c spec/models

やっとテスト実行。慣れてればさくっと出来るのだろうけど、調べながらやってたので時間食った。
成功したテストは緑で、失敗は赤で表示される。一般的なxUnitと同じである。
specの引数は

% ./script/spec -h

で。

クエリ確認

DBを見ても、テストに使ったデータは無い。実行したクエリはlogディレクトリ以下に、test.logとして残ってるはず。
見ると、トランザクション処理をやって、テストが終わったらロールバックしてるのが見て取れる。
自動で後始末してくれる。

感想

確かに、多対多(many_to_many)のテストなのに関係テーブルのデータを用意しなくて済むのが素晴らしい。
データの用意だけならyamlでも別にええやんって思ってたけど、これはでかい。記述量も減るし、yamlより分かりやすいし。
あーあとDB無関係なテスト調べてない。普通にTest::Unitでいいのかな。でもspec使えるっぽい。あとで調べる。




ところで。
rails使えないのにrailsのテスト手法調べるとか、TDDを言い訳にする事すら出来ない阿呆っぷり。