Everyday Rails - 6日目

前回、P.64でcreateのテストにidをパラメータで渡しているが(書籍自体そうなっている)、不要なので削除しておく。あってもStrong Paremetersの機能で弾かれるので、問題無いと言えばない。

8.フィーチャスペック

まず、この章ではブラウザを使ったテストを行うのだが、Nitrous.IO上なのでヘッドレスなテストにしたい。
PhantomJS、Poltergeistを利用する。

PhantomJS | PhantomJS

PhantomJSは、Nitrous.IO上のバージョンは1.7.0だった。
特に不都合はないかもしれないが、ローカルに最新(1.9.8)を持つことにした。

適当な箇所で展開して、bin/phantomjsを例えば~/.local/binの中に入れる。~/.local/binにはパスを通しておく。
Poltergeistの設定でphantomjsのpathを指定できるが、他の環境で使う場合は困るかもしれないのでそこでは指定しない。

# :
# Poltergeist
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist

# :
RSpec.configure do |config|
  # :
  config.use_transactional_fixtures = false
  # :

  # Screenshot Helper
  config.include Screenshot

  # DatabaseCleaner
  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
    • spec/support/shared_db_connection.rb
class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end

ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

screenshotsディレクトリ以下のファイルは.gitignoreで対象外にした方がよい。
クラス名など、もっとテストヘルパーメソッドがあれば適切に。
今は思いつかないので適当に。

$ mkdir screenshots
    • spec/support/screenshot.rb
module Screenshot
  def sc_file(file_name)
    Rails.root.join('screenshots', file_name)
  end
end
  • feature specの作成
$ ./bin/rails g rspec:feature users
$ ./bin/rails g rspec:feature about_us
  • spec/features/users_spec.rb
require 'rails_helper'

feature "Users", type: :feature do
  scenario 'adds a new user', js: true do
    admin = create(:admin)
    sign_in admin

    visit root_path

    expect {
      click_link 'Users'
      click_link 'New User'
      fill_in 'Email', with: 'newuser@example.com'
      find('#password').fill_in 'Password', with: 'secret123'
      find('#password_confirmation').fill_in 'Password confirmation',
        with: 'secret123'
      page.save_screenshot(sc_file('user_1.png'))
      click_button 'Create User'
    }.to change(User, :count).by(1)

    expect(current_path).to eq users_path
    expect(page).to have_content 'New user created'

    within 'h1' do
      expect(page).to have_content 'Users'
    end

    expect(page).to have_content 'newuser@example.com'
    page.save_screenshot(sc_file('user_2.png'))
  end
end

f:id:yossk:20141207150733p:plain
f:id:yossk:20141207150743p:plain

  • spec/features/about_us_spec.rb
require 'rails_helper'

feature "About BigCo modal", type: :feature do
  scenario 'toggles display of the modal about display', js: true do
    visit root_path

    about = 'About BigCo'
    content = 'BigCo produces the finest widgets in all the land'

    expect(page).not_to have_content about
    expect(page).not_to have_content content
    page.save_screenshot(sc_file('about_us_1.png'))

    click_link 'About Us'

    expect(page).to have_content about
    expect(page).to have_content content
    page.save_screenshot(sc_file('about_us_2.png'))

    within '#about_us' do
      click_button 'Close'
    end

    expect(page).not_to have_content about
    expect(page).not_to have_content content
    page.save_screenshot(sc_file('about_us_3.png'))
  end
end

スクリーンショットを取ってみたが、modalは取れなかった。残念。撮る方法があるのかな?
modalが表示仕切る前にスクリーンショットを撮っているだけだった。

  • about_us_2.png

f:id:yossk:20141207150708p:plain

今日の感想

とても簡単にヘッドレステストが実現できるのはいいね。
スクリーンショットもある程度は簡単に撮れるし、証跡作りが楽になるかも?プロじゃないので知らんけど。