Capybara+RSpecでエンドツーエンドなテストを書くときのTipsです
require "capybara/rspec"
の罠
require "capybara/rspec"
はafter(:each)
にCapybara.reset_sessions!`を入れてしまいます。
これによりit毎にCapybara.current_session
が変化してしまうため、以下のようなワンライナーshouldによるテストを難しくしています。
require File.dirname(__FILE__) + "/spec_helper"
feature "フォーム入力" do
before :all do
visit "/form.html"
fill_in "u_name", with:"テスト太郎"
click_button "送信"
end
context page do
its(:current_path) { should eq "/thanks.html" }
it { should have_selector "#u_name", text:"テスト太郎" }
end
end
回避方法(Capybara::DSLを使いたい場合)
require "capybara/rspec"
を使わず、自分で組み込みましょう
spec/spec_helper.rb:
require 'capybara/rspec/matchers'
require 'capybara/rspec/features'
RSpec.configure do |config|
config.include Capybara::DSL, :type => :feature
config.include Capybara::RSpecMatchers, :type => :feature
end
回避方法(Capybara::DSLを使わない場合)
テストを以下のようにします
require File.dirname(__FILE__) + "/spec_helper"
describe "フォーム入力" do
before :all do
Capybara.visit "/form.html"
Capybara.fill_in "u_name", with:"テスト太郎"
Capybara.click_button "送信"
end
context Capybara.page do
its(:current_path) { should eq "/thanks.html" }
it { should have_selector "#u_name", text:"テスト太郎" }
end
end
違いは以下の通り
-
describe :type => :feature
が不要 (無くともテストが実行される) -
feature
句、scenario
句等が使えない - 毎度
Capybara
をつける必要がある
注意
Capybara.reset_sessions!をafter(:all)あたりでやっておきましょう。さもないと、遷移状態がクリアされないのでテストが不安定になりますよ。
SSLサーバ証明書の検証を抑制する
無効なSSLサーバ証明書で動いているサーバへのテストを行う方法です
capybara-mechanizeの場合
opensslによる検証を抑制します
spec/spec_helper.rb:
require "openssl"
OpenSSL::SSL.module_eval { remove_const(:VERIFY_PEER) }
OpenSSL::SSL.const_set(:VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE)
I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil
参考資料
これをやらなかった場合のエラーメッセージ
RuntimeError:
Received the following error for a GET request to https://127.0.0.1: 'hostname "127.0.0.1" does not match the server certificate'
capybara-webkitの場合
SSL関連のエラーを抑制したCapybaraドライバを定義し、それを利用するようにします
spec/spec_helper.rb:
Capybara.register_driver :webkit_ignore_ssl do |app|
driver = Capybara::Webkit::Driver.new(app)
driver.browser.ignore_ssl_errors
driver
end
Capybara.configure do |config|
config.default_driver = :webkit_ignore_ssl
end
参考資料
これをやらなかった場合のエラーメッセージ
Capybara::Webkit::InvalidResponseError:
Unable to load URL: https://127.0.0.1 because of error loading https://127.0.0.1: Unknown error
Cookieを持たせる方法
capybara-mechanizeの場合
require "uri"
page.driver.browser.agent.cookie_jar.add URI.parse(Capybara.app_host), Mechanize::Cookie.new("cookie_key", "cookie_value", {domain:".example.com", expire:Time.now+86400, path:"/"})
capybara-webkitの場合
require "cgi"
page.driver.browser.set_cookie("cookie_key=#{CGI.escape('cookie_value')}; expires=#{(Time.now+86400).strftime("%a, %d %b %Y %H:%M:%S GMT")}; domain=.example.com; path=/;")