PerlerのRuby日記

Rubyとか

Mac + Webkit + Rails + RSpec + Capybaraによるテスト

昨日のテストを、レンダリングエンジンにWebkit(QtWebKit)を使ってテストする。
こちらのいいところは、完全にheadlessなのでモニタがない環境でもテストしやすいところ。

Gemfile

group :test do
  gem 'rspec-rails'
  gem 'capybara'
  gem 'selenium-webdriver'
  gem 'capybara-webkit' # 追加
end

bundle installでエラーが出るかもしれない。

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/rightgo09/local/rvm/rubies/ruby-2.1.1/bin/ruby extconf.rb
Command 'qmake -spec macx-g++ ' not available

Makefile not found

homebrewでqtを入れておけばok。

brew install qt

spec_helper.rb

require 'capybara/rspec'
Capybara.default_driver = :selenium

↑これを↓こうする

require 'capybara/rspec'
Capybara.default_driver = :webkit
Capybara.javascript_driver = :webkit

Capybara.javascript_driverは、テストに:js => trueまたは@javascriptタグが付いているテストに使われるJSエンジン。デフォルトは:selenium
なので、default_driverが:webkitでも、javascript_driverを変更しない場合、:js => trueのテストはFireFoxでテストされることになる。

describe "the signin process", :type => :feature, :js => true do
  # something
end


Capybara.current_driverやCapybara.javascript_driverを使ってこれらを変更したり、
あるいはJenkinsのマトリクスで外部変数を読み込むようにすれば、
FireFoxChrome(いまは違うっけ?)とSafari辺りは自動テストできるんじゃないかと思う。

Mac + FireFox + Rails + RSpec + Capybaraによるテスト

Macの環境で実際にブラウザを使ったテストがしたかった。
iOSビルドの関係でMacの上にJenkinsが載っていることもあるので。

FireFox

インストール。

Gemfile

以下を追加して、bundle install。

group :test do
  gem 'rspec-rails'
  gem 'capybara'
  gem 'selenium-webdriver'
end

spec_helper

以下を追加。

require 'capybara/rspec'
Capybara.default_driver = :selenium

ストファイ

spec/features/signin_spec.rb
require "spec_helper"

describe "the signin process", :type => :feature do
  #before :each do
  #  User.make(:email => 'user@example.com', :password => 'caplin')
  #end

  it "signs me in" do
    visit '/sessions/new'
    within("#session") do
      fill_in 'Login', :with => 'user@example.com'
      fill_in 'Password', :with => 'password'
    end
    click_button 'Sign in'
    expect(page).to have_content 'Success'
  end
end

ルーティングとコントローラとビュー

config/routes.rb
  get "sessions/new"
  post "sessions/create"
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
  end

  def create
  end
end
app/views/sessions/new.html.erb
<%= form_tag sessions_create_path, method: :post, id: "session" do %>
  <%= text_field_tag "email", nil, id: "Login" %>
  <%= text_field_tag "password", nil, id: "Password" %>
  <%= submit_tag "Sign in" %>
<% end %>
app/views/sessions/create.html.erb
<h1>Success</h1>

テストを実行

$ bundle exec rspec spec/features/signin_spec.rb

一瞬FireFoxが開いて、ページがちらっと出てきて、すぐに消える。

$ bundle exec rspec spec/features/signin_spec.rb
.

Finished in 2.61 seconds
1 example, 0 failures

Randomized with seed 43635


簡単ですね。

Sinatraのエラーハンドリング

http://www.sinatrarb.com/intro.html#Error%20Handling

こちらを見ると例外はRackオブジェクトのsinatra.errorに入っているとあるが、ブロック引数としても受け取ることができる。
(バージョン1.4.4で確認)

require "sinatra"

# developmentモードでもデバッグ表示させない
set :show_exceptions, false

# ブロック引数で例外オブジェクトを受け取る
error do |e|
  status 500
  # これでもできるけど
  #body env['sinatra.error'].message
  # これでもよい
  body e.message
end

get "/hoge" do
  raise "hoge"
end
$ bundle exec ruby app.rb
$ curl localhost:4567/hoge
hoge