ぽかぽかウンティの自由帳

ぽかぽか動物園から投稿します。

rspec で fixture と factorygirl とを併用したい

会社のプロジェクトで rspec を使ってテストしているが、チームメンバーに factorygirl を使っていることを伝え忘れてしまい、fixture と factorygirl のテストケースが混在する形になってしまった。

各々が自分で書いたテストケースだけを bundle exec rspec で指定して実行すると成功する。しかし、全体を通して、つまり fixture を使ったケースと factorygirl を使ったケースとが混在する形で bundle exec rake spec すると、意図しない形で落ちてしまう。

log/test.log で流れるクエリを見ると、fixture の挙動が以下のようになっていた。

  1. delete
  2. insert
  3. commit

spec/spec_helper.rb で「config.use_transactional_fixtures = true」にしているのに commit されていたのだ。

だからケース実行後に DB にゴミデータが残ってしまい、後続のケースでゴミデータがない前提で書いているテストが落ちてしまっていた。例えば、「Hogehoge.all.should be_blank」とか。

今更 fixture か factorygirl のどちらかに統一するのは工数がかかるので、どうにか共存・併用できないか設定を模索したところ、以下の設定ですべてのケースで rollback されるようになった。

config.around(:each) do |ex|
  ActiveRecord::Base.transaction do
    ex.run
    raise ActiveRecord::Rollback
  end
end

「config.use_transactional_fixtures」は false で良い。念の為入れていた database cleaner の設定も全部消した。

database cleaner いらないんじゃねぇか疑惑。truncation 設定すると最初に全テーブルに対して truncate が走るから糞重いしね。