だるろぐ跡地

2009-06-22

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

| 03:52 | 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を言い訳にする事すら出来ない阿呆っぷり。


参考リンク

http://www.func09.com/wordpress/archives/532

http://d.hatena.ne.jp/yuum3/20081111/1226369036

http://jp.rubyist.net/magazine/?0021-Rspec