I'm using rspec, capybara and launchy to test my web application.
Here's my spec:
require 'spec_helper'
describe "Routes" do
describe "GET requests" do
it "GET /root_path" do
visit root_path
page.should have_content("All of our statuses")
click_link "Post a New Status"
page.should have_content("New status")
fill_in "status_name", with: "Jimmy balooney"
fill_in "status_content", with: "Oh my god I am going insaaaaaaaaane!!!"
click_button "Create Status"
page.should have_content("Status was successfully created.")
click_link "Statuses"
page.should have_content("All of our statuses")
page.should have_content("Jimmy balooney")
page.should have_content("Oh my god I am going insaaaaaaaaane!!! ")
save_and_open_page
end
end
end
My .rspec
--color
--order default
and my spec_helper.rb:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
DatabaseCleaner.clean
end
config.after(:each) do
DatabaseCleaner.clean
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
If you look back at my spec, you'll see a rspec spec that uses capybara to browse my application, and finishes by calling the launchy gem's save_and_open_page method to open this final page in a browser for a human to look at. At this final page, however, there is no javascript or css displayed, just pure HTML.
Does anyone have any ideas why this would be? I want to test javascript, and would prefer it if all assets were loaded.
Inside config.before(:suite) do
add:
%x[bundle exec rake assets:precompile]
to precompile your Rails assets then in your test.rb environment file add:
config.action_controller.asset_host = "file://#{::Rails.root}/public"
config.assets.prefix = 'assets_test'
to point to the location of the precompiled assets. Now you can use assets when you run Capybara. Note: make sure if you are using git to ignore that new folder.
You can just add to test.rb:
config.assets.compile = true
Related
I am just getting started on rspec, and I may have included to much in the first go. I followed this guide but cant seem to get it all to come together.
I have a Model called Photo, so I have created a Factory girl for that:
# spec/factories/photo.rb
FactoryGirl.define do
factory :photo do
date_taken { Faker::Date.backward(14) }
end
end
I use this in a test:
#spec/models/photo_spec.rb
require 'rails_helper'
RSpec.describe Photo, type: :model do
it "has a valid factory" do
expect(photo).to be_valid
end
end
But I get the following, indicating that the photo factory is not loaded...
rspec spec/models/photo_spec.rb
Failures:
1) Photo has a valid factory
Failure/Error: expect(photo).to be_valid
NameError:
undefined local variable or method `photo' for #<RSpec::ExampleGroups::Photo:0x00000004b769f8>
# ./spec/models/photo_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.29491 seconds (files took 7.67 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/models/photo_spec.rb:4 # Photo has a valid factory
My config is:
#spec/rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
require 'shoulda/matchers'
require 'database_cleaner'
require 'support/factory_girl'
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
# Checks for pending migration and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
in support dir:
#spec/support/factory_girl.rb
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
#spec/support/database_cleaner.rb`enter code here`
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Down in the comments section on the linked guide, there's a comment by Rhys Davis on 11 Jan 2016
Although in the Model Specs section I had to add the following to
rails_helper.rb: config.include FactoryGirl::Syntax::Methods
then also add the following to my contact_spec.rb: contact =
build(:contact)
and then a reply by Arkadiusz Zdanowski on 5 Sep
Yes, without those lines I got the following error:
Failures:
1) Contact has a valid factory
Failure/Error: expect(contact).to be_valid
NameError:
undefined local variable or method `contact' for #
Which is the same error you're getting now, so adding those 2 lines should probably fix the issue for you.
some_spec.rb
require 'spec_helper'
describe "Authentication." do
subject { page }
let(:user) { FactoryGirl.create(:user) }
before {visit new_user_session_path}
describe "Login with username" do
before do
fill_in "Login", with: user.username
fill_in "Password", with: user.password
click_button "Sign in"
end
expect(page).to have_content('Signed in successfully.')
end
describe "Login with email" do
before do
fill_in "Login", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
expect(page).to have_content('Signed in successfully.')
end
end
spec_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include Capybara::DSL
config.include Rails.application.routes.url_helpers
end
What's the problem? After run command terminal returned error: undefined local variable or method 'page'.
The following question did not help me:
rspec+capybara undefined local variable or method
I think you should remove subject { page } from your spec.
page is defined in Capybara.
Important: wrap your expectations by it blocks!
HI i am trying to test a form by filling some data through capybara . My test runs without any error but i can not see that data either in test or development databases. My test is in "spec/feature/FILE NAME". My test is something like
require 'spec_helper'
feature "New Application" do
scenario 'has 200 status code if logged in' do
visit '/applications/new?id=.........'
fill_in 'application[applicants_attributes][0][first_name]', :with => 'Rose'
fill_in 'application[applicants_attributes][0][first_name]', :with => 'Farmer'
click_link 'sbmt'
current_path.should == '/applications/new'
page.status_code.should be 200
end
end
Need Help please!!!!
My spec_helper is something like
require 'simplecov'
SimpleCov.start do
add_filter '/spec/'
add_filter '/config/'
add_filter '/lib/'
add_filter '/vendor/'
end
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
# Add this to load Capybara integration:
require 'capybara/rspec'
require 'capybara/rails'
require 'rspec/autorun'
require 'crack'
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new(app, :headers => { 'User-Agent' => 'Capybara' })
end
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
config.include Capybara::DSL, type: :feature
RSpec.configure do |config|
config.use_transactional_fixtures = false
#config.use_transactional_fixtures = false
config.before :each do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.start
end
config.after do
DatabaseCleaner.clean
end
end
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
My rspec output is
Failures:
1) New Application has 200 status code if logged in
Failure/Error: Application.where("first_name = 'Rose' AND last_name = 'Farmer'").count.should == 1
expected: 1
got: 0 (using ==)
# ./spec/features/applications_controller_spec.rb:23:in `block (2 levels) in <top (required)>'
Finished in 0.7381 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/features/applications_controller_spec.rb:4 # New Application has 200 status code if logged in
Randomized with seed 49732
Coverage report generated for Cucumber Features to /home/nomi/homesbyhaven/coverage. 241 / 616 LOC (39.12%) covered.
Problem is i am not able to save the data to database . if i remove the check for the data in Application table from the test. it passes. but how can i verify that it is really passing. i mean to say there is no issues.
Thanks
I think the issue here is that you are testing the wrong thing. A feature (integration) spec tests the system the way a user interacts with it. So as much as possible, your test should limit itself to the activities a user can perform. Instead of checking that, for example, after adding a user the User.count goes up by one, have the test do the same thing a user would do to verify that the the action was successful. You could visit the user page to see that the user was added, or have an element on the page that tells you how many users exist.
Remember that the test server and the browser use separate processes. This can cause timing issues where you expect that the server has completed an action (eg. adding a user) in one process, but the database change is occurring in another process. You can avoid those issues by having the test browser imitate a user's actions. Do the database testing in model specs.
By default the test database is cleared after each test. So that each time you run the tests, you've got a clean slate.
If you don't want this to happen you can change the config in you spec/spec_helper.rb to
config.use_transactional_fixtures = false
but if you not clearing the db after each test, then any records created from the previously run test could change the result of the next test. Giving you a false positive or negative
You will have a block like below in your spec/spec_helper.rb . I do not recommend disabling the transactional fixture as it will cause lot of problems when you have more than one test.
RSpec.configure do |config|
# Mock Framework
config.mock_with :rspec
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# Render views when testing controllers
# This gives us some coverages of views
# even when we aren't testing them in isolation
config.render_views
end
Instead what you can do is, make the database check as an assertion in your test case
require 'spec_helper'
feature "New Application" do
scenario 'has 200 status code if logged in' do
visit '/applications/new?id=.........'
fill_in 'application[applicants_attributes][0][first_name]', :with => 'Rose'
fill_in 'application[applicants_attributes][0][last_name]', :with => 'Farmer'
click_link 'sbmt'
current_path.should == '/applications/new'
Application.where("first_name = 'Rose' AND last_name = 'Farmer'").count.should == 1
page.status_code.should be 200
end
end
If the above test fails, then your functionality is not working as expected
You cannot use transactional fixtures if you are using anything other than ActiveRecord.
If you are using MongoID you can use Database Cleaner with Truncation Strategy
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before :each do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.start
end
config.after do
DatabaseCleaner.clean
end
end
For a while I was using Selenium / Spork / Rspec, with cache_classes on false, and everything seemed to be working.
In switching over to webkit, I've started to get errors related to cache_classes (e.g. Expected User, got User), so I've been fighting with it to try to get cache_classes set to true.
However no matter what I do, I end up with the following error:
Capybara::Driver::Webkit::WebkitInvalidResponseError:
Unable to load URL: http://127.0.0.1:56398/login
I have tried all kinds of things... including:
ActiveSupport::Dependencies.clear in both the prefork and each _run blocks
The code here: http://my.rails-royce.org/2012/01/14/reloading-models-in-rails-3-1-when-usign-spork-and-cache_classes-true/
Starting to wonder if I should just live with cache_classes = false, and figure out how to avoid the Factory girl errors. Any help would be appreciated. My spork file is as follows:
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'
require 'database_cleaner'
require 'factory_girl'
require 'authlogic/test_case'
require 'email_spec'
include Authlogic::TestCase
require File.expand_path("../../config/environment", __FILE__)
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
ApplicationController.skip_before_filter :activate_authlogic
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
config.include Capybara::DSL
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation, {:except => %w[ages coefficients weights1 weights2 weights3 weights4 weights5 weights6 weights7 weights8 etfs]}
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.start
Capybara.current_driver = :webkit if example.metadata[:js]
#Capybara.current_driver = :selenium if example.metadata[:js]
activate_authlogic
ActiveRecord::Base.instantiate_observers
end
config.after(:each) do
DatabaseCleaner.clean
Capybara.use_default_driver if example.metadata[:js]
end
Capybara.default_selector = :css
end
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
## SUPPORT METHODS ##
## (erased for clarity) ##
## ##
ActiveSupport::Dependencies.clear
end
Spork.each_run do
#FactoryGirl.reload
# Required to fix a recurring error when testing Active_Admin stuff
# See here: http://railsgotchas.wordpress.com/2012/01/31/activeadmin-spork-and-the-infamous-undefined-local-variable-or-method-view_factory/
# Delete at some point if active admin or whoever fixes this
ActionView::Template.register_template_handler :arb, lambda { |template|
"self.class.send :include, Arbre::Builder; #_helpers = self; self.extend ActiveAdmin::ViewHelpers; #__current_dom_element__ = Arbre::Context.new(assigns, self); begin; #{template.source}; end; current_dom_context"
}
#ActiveSupport::Dependencies.clear
end
UPDATE : Adding an example spec just in case it helps....
describe "Items" do
before(:each) do
#user = Factory.create(:user)
activate_authlogic
b = # something not important
end
describe "usage paths" do
it "the form directly from the basic_simulation show page should have correctly functioning javascript validation", :js => true do
request_sign_in(#user) # This is a helper method which goes through the login form
visit '/basic_simulation'
fill_in "amount", :with => "-5000"
click_button "Calculate"
page.should have_selector("label.jquery-validator.amount-error", :text => "Please enter a value greater than or")
fill_in "amount", :with => "5000"
click_button "Calculate"
page.should have_selector("input#amount", :value => "5000")
end
end
You are having issues due to threading problems with Capybara-webkit and the test suite.
Jose Valim explains it much more clearly in a recent blog post.
If you follow his recommendations then you should be able to turn on transactional fixtures, remove database cleaner altogether and no longer have issues with your data during tests while using capybara-webkit. You'll get a nice boost in testing performance as well.
The trick though is to make sure that Jose's suggestion is in the Spork.each_run block or it will not work. For clarity here are the relevant parts of my spec_helper.rb.
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
Capybara.default_driver = :rack_test
Capybara.default_selector = :css
Capybara.javascript_driver = :webkit
end
end
Spork.each_run do
if Spork.using_spork?
ActiveRecord::Base.instantiate_observers
end
require 'factory_girl_rails'
# Forces all threads to share the same connection, works on Capybara because it starts the web server in a thread.
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
end
A few other small suggestions:
If you are using the latest version of factory_girl_rails then you
should be using require factory_girl_rails in the Spork.each_run
block and require factory_girl should be removed from the prefork
The latest factory_girl_rails also no longer requires ActiveSupport::Dependencies.clear at all, although some people are still having issues without it so you should test removing it.
I'm still not sure about the need for ActiveRecord::Base.instantiate_observers but in any case you would only need it if you are using observers and I understand that it should be in the each_run block.
Try all that and see if it works for you.
When running the rspec I get:
C:/www/kill/spec/games_controller_spec.rb:4:in block in <top
(required)>': undefined local variable or methodrender_views'
games_controller_spec.rb
require 'spec_helper'
describe GamesController, "creating a new game" do
render_views
fixtures :games
it "should redirect to index with a notice on successful save" do
Game.any_instance.stubs(:valid?).returns(true)
post 'create'
assigns[:game].should_not be_new_record
flash[:notice].should_not be_nil
response.should redirect_to(menu_items_path)
end
end
spec_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
#config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
end
gems:
C:/Ruby192/lib/ruby/gems/1.9.1/gems/rspec-2.7.0
C:/Ruby192/lib/ruby/gems/1.9.1/gems/mocha-0.10.0
Your controller specs should be in the spec/controllers/ folder. However, you may want for some reason to have some other files that run controller specs (for example, I'm testing markup validation in a separate test file).
You can do this :
describe GamesController, "creating a new game", :type => :controller do
And this should do the trick !
You should place your controller specs inside a spec/controllers directory. RSpec is including these methods based on this, AFAIK.
In my case my test was already in spec/controllers/. I needed to add config.infer_spec_type_from_file_location! inside the RSpec.configure do |config| loop in spec_helper.rb. I had updated rspec from 2.x to 3.x without realizing it, and that config is needed for controller tests from 3.x.
If you test the views, RSpec have the spec/requests directory for that, it will render views by default. (See the doc)
this problem may be caused by your Gem rspec-rails version. downgrade it back to 2.x solved my problem:
# edit your Gemfile
gem "rspec-rails", "2.14.2"