Ruby
Rails
RSpec

Rspecの文法の基礎

More than 3 years have passed since last update.


spec/order_spec.rb

describe Order do

before do
order.add_entry(LineItem.new(:item => Item.new(
:price => Money.new(1.11, :USD)
)))
end

let(order) { Order.new }

it "sums the prices of its line items" do
order.add_entry(LineItem.new(:item => Item.new(
:price => Money.new(2.22, :USD),
:quantity => 2
)))
expect(order.total).to eq(Money.new(5.55, :USD))
end
end


Rspecrspec-core, rspec-expectations, rspec-mocksの3つにわかれており、それぞれRspecの基本文型、多様な比較演算、モックオブジェクトを定義している。このドキュメントは、文法に焦点を当てるため、rspec-coreの中の基礎的な部分と、Rails用にrspec-rails, capybaraが拡張する文法について触れる。

テストの中身の書き方については、http://qiita.com/awakia/items/d880250adc8cdbe7a32f を参照


基本文型

https://github.com/rspec/rspec-core

https://www.relishapp.com/rspec/rspec-core/v/3-0/docs/example-groups/basic-structure-describe-it


spec/models/class_spec.rb

describe <クラス名> do

it "<期待する動作の内容>"
# ...
end

context "<条件の内容>" do
it "<contextの条件下で期待する動作の内容>" do
# ...
end
end
end


ここで、



  • contextは、describeに置き換え可能


  • itは、specifyまたはexampleに置き換え可能

なので、文脈に合わせて使いやすい用語を使えば良い。

なお、デフォルトの設定では、名前として<クラス名>_spec.rbというようにサフィックスとして_spec.rbがないとrspecコマンドで全体を走らせた時に無視されるようになるので気をつけること。


何をしているか

なお、topレベルのdescribeはExampleGroupを生成するが、役割はそれだけではない。


Railsを使っている場合

rspec-railsというのを使う。

これは、expect ... toの後に使える


  • be_a_new

  • render_template

  • redirect_to

  • route_to

  • be_routable

などのRails用のMatcherを提供する他、


  • Model

  • Controller

  • View

  • Request

  • Feature

  • Mailer

  • Routing

  • Helper

など、それぞれのタイプの特徴に合わせたスペックの書き方を提供する。

例えばモデルタイプのテストだとspec/modelsの下におくか

describe ... type: :modelとしてテストを書く。

それぞれのタイプにより何がロードされるかや、使えるメソッドなどが異なり、ここに書ききれないので、それぞれのテストを書く際にドキュメントを参照すると良い。

ドキュメントは以下だが、概要はgithubの方がわかりやすいので詳しく知りたくなった時のみこちらを参照すると良い。

https://www.relishapp.com/rspec/rspec-rails/v/3-0/docs/directory-structure


Capybaraを使っている場合

rspec-railsのfeatureテストはほぼcapybaraの使用を前提としている。

Capybaraはユーザーがブラウズする課程をテストでそのまま書くようなFeatureテストを作成するときに便利なgem

https://github.com/jnicklas/capybara#using-capybara-with-rspec

これを使っている場合、



  • describe ... type: :featureの代わりにfeature


  • beforeの代わりに、background


  • itの代わりに、scenario


  • letの代わりにgiven

が使えるようになり、より自然な英語で以下のように書けるようになる。


spec/features/signing_in_spec.rb

feature "Signing in" do

background do
User.make(:email => 'user@example.com', :password => 'caplin')
end

given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') }

scenario "Signing in as another user" do
visit '/sessions/new'
within("#session") do
fill_in 'Login', :with => other_user.email
fill_in 'Password', :with => other_user.password
end
click_link 'Sign in'
expect(page).to have_content 'Invalid email or password'
end
end