読者です 読者をやめる 読者になる 読者になる

ここにタイトルが入ります

デザイン&プログラミングのことも書くし、それ以外のことも書く。

【RSpec】before :allの罠。

ruby Rails

テスト、書いてますか?


私の会社では今のプロジェクトからテストを書き始めたので、
RSpec本でミニ社内勉強会とかしたりしてすこしづつテストに慣れようとしています。
テスト書きづらいひどいコードになっていることに気付かされ凹みますねw


それもこれも、いつか継続的デプロイ環境?を社内に構築するため!
…いつか毎日自動でテストが流れて画面のテストも自動化されてワンクリックで本番環境にデプロイできるようにするのが夢です(*´∀`)

いつになるかわかんないけれども。
一日にしてならず。


テストに関してはほんとにわからない事だらけです。
その中でも、最近はまったことについてメモ。

「before」ってあるじゃないですか。
例えば以下のようなRSpecコードがあった場合、
(テストにはなってないですすみません)

context "execute this test" do
  
  before(:each) do
    puts "say"
  end
  
  after(:each) do
    puts "thank you"
  end

  it "should say hello" do
    puts "hello!"
  end
  
  it "should say good morning" do
    puts "good mornig"
  end

end

実行結果は
say → hello! → thank you → say → good morning! → thank you
となるはず。
it〜で書かれたテストが実行される前に「before」が、実行されたあとに「after」が実行されます。
テスト毎に実行されます。

で、上記の:eachという部分を:allに変えると、実行結果は
say → hello! → good morning! → thank you
となるはずです。

:allとすると、そのブロックが実行される最初に1度だけbeforeが、最後に一度だけafterが実行されます。
上ではcontextに渡されてるブロックですね。


before :allの罠その① rollbackされない

よくテストを実行する際、最初にbeforeでテストデータをDBに作ってから…ということがあると思います。
これ、:eachで実行した場合は勝手にテスト終了後Rollbackされるのですが、:allの時はRollbackされません。
作ったデータそのまま残ります。

もし:allでデータを作る際は、after :allのなかでお掃除してあげましょう。

〜参考になりました!!〜
http://journal.sooey.com/35:test


before :allの罠その② Mockが使えない

未実装の部分を含むテストを書いたり、モジュール間を疎結合するために便利なのがMockやStubですよね。
ただ、before :allのブロック内でRSpec::Mock(stubとかmockとかdoubleとか)のメソッドを使おうとすると、
no method errorで怒られるんですよね…

なんでかなーと思って調べてみるとどうやら仕様…?

〜参考になりました!!〜
Issue #92: stub method not found in before(:all) block · rspec/rspec-mocks · GitHub


…詳しくはわからないけど、
「テスト毎にMockとかStubはリセットされるからエラーになっちゃうんだよ。これから修正される予定はないよHAHAHA!!」
みたいなことだと思うんですけど。


実装されてないってことは、RSpecを使うにあたりそのようなテストを書く場面があまりないもしくは間違っている、て事なのかも。



テスト書くのが当たり前になるように頑張ります。
余談ですが、CucumberってRSpec使ってる人はみんな取り入れてるのかな〜??