RSpec
Memo
within
セレクトボックスをクリックしてから選択、というような場合capybaraは不安定になることがある。 まだ表示されてないのに、クリックするためにクリックするポイントがずれたりする。
安直なのはsleepすることだが、いい方法もある。 親要素全体が表示されてから、クリックする。
within '親要素' do find('li', text: 'セレクトボックスの中身').click end
ENVをテストするためのヘルパー
ENVを変えてテストしたいときがある。 https://github.com/rspec/rspec-rails/issues/1279#issuecomment-70275896 ヘルパーを追加する。
module EnvHelpers def with_env_vars(vars) original = ENV.to_hash vars.each { |k, v| ENV[k] = v } begin yield ensure ENV.replace(original) end end end
RSpec.configure do |c| c.include EnvHelpers end
it 'does something with the FOO environment variable' do with_env_vars 'FOO' => 'bar' do # logic that depends upon ENV['FOO'] goes here end end
テスト結果にSQLを出力する
どのようなSQLが発行されるか確認できると便利。
RSpec.describe do before do ActiveRecord::Base.logger = Logger.new(STDOUT) end it do ... end end
request specでsessionメソッドを使う
allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return({})
simplecovカバレッジ
COVERAGE=true bundle exec rspec spec/requests/user_spec.rb
open coverage/index.html
たまに失敗するパターン
system specではよくある。
読み込み前に検証して失敗する
expect(page).to have_text 'aaa', wait: 5 #発見できなかったときの最大待ち時間を伸ばす
並び順に依存したテスト
同じ秒数に作成されたとき、createした順番に並ばない可能性がある。
model1 = create(:model) model2 = create(:model)
created_atでソートして表示しているとして、この作成順にソートされるわけではない。 秒数が同じときはidなどがソートに使われるだろう。 1つcreateするのにはわずかな時間なので、たまに失敗するだけで気づきにくい。
チェックボックス
チェックに少し時間がかかるのでたまにチェックせずに送信して失敗する。
check aaa expect(page).to have_checked_field(aaa), wait 5 # チェックを確認する
Reference
ruby on rails - What is the purpose of a `transient do` block in FactoryBot factories? - Stack Overflow
FactoryBotのtransientの使い方。
ruby on rails - Check the dimensions of an img with RSpec/Capybara? - Stack Overflow
jQueryを使って存在チェックする方法。
Better Specs. Testing Guidelines for Developers.
RSpecのベストプラクティス集。
Introduction - rspec-style-guide
可読性の高いテストコードを書くためのRSpecのスタイルガイド。