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
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.
I'm quite desperate since moving our test suite from Minitest to RSpec. All the controller and model tests run fine so far, but since trying to port (formerly passing/working) feature tests like the following I ran into trouble...
feature 'Create place' do
scenario 'create valid place as user' do
login_as_user
visit '/places/new'
fill_in_valid_place_information
click_button('Create Place')
visit '/places'
expect(page).to have_content('Any place', count: 1)
end
...
def fill_in_valid_place_information
fill_in('place_name', with: 'Any place')
fill_in('place_street', with: 'Magdalenenstr.')
fill_in('place_house_number', with: '19')
fill_in('place_postal_code', with: '10963')
fill_in('place_city', with: 'Berlin')
fill_in('place_email', with: 'schnipp#schnapp.com')
fill_in('place_homepage', with: 'http://schnapp.com')
fill_in('place_phone', with: '03081763253')
end
end
Unfortunately this does not lead to a DB commit which makes the test fail. It does not fail if i pry into the test and manually create the requested place. I tried different methods in order to trigger the button but nothing worked so far.
This is how my rails_helper.rb looks like:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
require 'pry'
def validate_captcha
fill_in 'captcha', with: SimpleCaptcha::SimpleCaptchaData.first.value
end
def login_as_user
user = create :user, email: 'user#example.com'
visit 'login/'
fill_in 'sessions_email', with: 'user#example.com'
fill_in 'sessions_password', with: 'secret'
click_on 'Login'
end
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, phantomjs_options: ['--ignore-ssl-errors=true'])
end
Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, no_transaction: true) do
DatabaseCleaner.strategy = :truncation
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
config.include Capybara::DSL
config.include Rails.application.routes.url_helpers
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
end
Does anyone have a clue about a possible cause? Gem versions:
capybara 2.12.0
rspec 3.5.0
rails 4.2.7.1
best and thanks,
Andi
--- Update
I added fill_in_valid_place_information method
This is how the test fails with or without a Capybara JS driver enabled (shouldn't matter in case of this test as the feature does not use any JS). Unfortunately it doesn't give any real hints to work with...
1) Create place create valid place as user
Failure/Error: expect(page).to have_content('Any place', count: 1)
expected to find text "Any place" 1 time but found 0 times in "KIEZ KARTE Find places Here comes a list of all POIs currently available in our database. If you are looking for a specific location please enter parts of its descriptive features into the 'Search' field. Search: Name Postal code Categories No data available in table"
Timeout reached while running a *waiting* Capybara finder...perhaps you wanted to return immediately? Use a non-waiting Capybara finder. More info: http://blog.codeship.com/faster-rails-tests?utm_source=gem_exception
--- Update 2
I found the issue which is not capyara-related. Actually I forgot to transfer a stub response for an API we're calling. Thanks everybody for participating in my struggle!
There are a number of potential issues in your test that could be causing what you are seeing, it would be easier to narrow down in the future if you included the actual error message(s) your test produces.
Your scenarion/feature isn't tagged with :js metadata to activate using the Capybara driver. It's possible you've specified Capybara.default_driver somewhere, but if so then your DatabaseCleaner config is wrong
Use the recommended DatabaseCleaner configuration from https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example . The driver name detection will work if you have specified Capybara.default_driver as mentioned in #1 and also with the :js/:driver metadata usage pattern. Additionally, the append_after/after difference is important to reduce test flakiness
Your login_as_user method needs to verify the login has completed before returning. This is because click_on 'Login' can trigger asynchronously and return before the login actually occurs. This leads to the visit you call immediately following aborting the login, preventing the session cookie from being sent, and ending up with a non logged in user when you expected the user to be logged in. To fix this you need something like
def login_as_user
...
click_on 'Login'
expect(page).to have_text('You are now logged in!') #whatever message is shown on successful login, or use have_css with some element on the page that only exists when a user is logged in (user menu, etc)
end
The same issue exists between click_button('Create Place') and visit '/places' where the visit can effectively cancel the effects of the button click
I have an RSpec feature spec that tests the login for my app. It passes when I run it in RSpec with Capybara, but when I try to run it flagged with js: true using Capybara-webkit, it fails. This is a problem because my entire app is behind the login, and if I can't get this bit to run I don't know how to do feature specs for the rest of the app.
Here's what I have tried:
Installing all the Capybara-webkit dependencies listed here. I'm running my app in a Docker container built on the ruby:2.3 image, which is built on Jessie.
Setting up DatabaseCleaner per this blog post. My database_cleaner.rb file is below.
Using the Headless gem (headless.rb below)
Running RSpec like so: xvfb-run -a bin/rspec spec/features/log_in_spec.rb (seems no different than running it normally with Headless)
How do I get my login specs to work under Capybara-webkit? Some of my specs will need to be flagged for JS and some won't, but they'll all need the user to be logged in. Thank you.
log_in_spec.rb
require 'rails_helper'
RSpec.feature "Log in", type: :feature do
scenario "as admin" do
user = create(:admin)
# Tried this instead of with Capybara, works with Capybara but not capybara-webkit
# login_as user, scope: :user, run_callbacks: false
visit root_path
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
find('.btn-primary').click
expect(page).to have_content('Admin')
end
end
spec_helper.rb
require 'capybara/rspec'
require 'paperclip/matchers'
RSpec.configure do |config|
Capybara.javascript_driver = :webkit
Capybara.app_host = 'https://192.168.99.101'
config.include Paperclip::Shoulda::Matchers
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
mocks.verify_doubled_constant_names = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.disable_monkey_patching!
if config.files_to_run.one?
config.default_formatter = 'doc'
end
end
rails_helper.rb
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 'spec_helper'
require 'rspec/rails'
require 'capybara/rails'
require 'devise'
require 'support/controller_macros'
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.use_transactional_fixtures = false
config.filter_rails_from_backtrace!
config.include Warden::Test::Helpers
config.before :suite do
Warden.test_mode!
end
config.after :each do
Warden.test_reset!
end
end
# Added headless gem and this code thanks to this post: http://stackoverflow.com/a/28706535/3043668
if ENV['HEADLESS']
require 'headless'
headless = Headless.new
headless.start
at_exit { headless.stop }
end
spec/support/database_cleaner.rb
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
spec/support/headless.rb
RSpec.configure do |config|
config.around type: :feature do |example|
Headless.ly do
example.run
end
end
end
spec/support/capybara.rb
Capybara::Webkit.configure do |config|
config.debug = true
config.allow_unknown_urls
config.timeout = 5
config.ignore_ssl_errors
config.skip_image_loading
end
Here is a gist of the debug output from Capybara-webkit when I run the test. It looks like it's trying the same thing over and over.
UPDATE
I removed my Capybara.app_host setting, and the non-JS test still passes, but when I run it under capybara-webkit, I see this in the debig output:
Received 0 from "https://127.0.0.1:37193/login"
Page finished with false
Load finished
Page load from command finished
Wrote response false "{"class":"InvalidResponseError","message":"Unable to load URL: http://127.0.0.1:37193/login because of error loading https://127.0.0.1:37193/login: Unknown error"}"
Received "Reset()"
Started "Reset()"
undefined|1|SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
It's trying to visit("/login") and it is being redirected to the https version, and this is making it fail. How do I make it succeed?
The first reason is that the record after save procedure c=keep not the password in plain view, but seems that it is good in this case:
user = create(:admin)
# ...
user = User.first # wrong way
#...
fill_in 'Password', with: 'password'
The second reason in fail to login is that factory girl and capybara uses separate connections, so and data created in one session isn't available in another. To fix it use single connection patch (put it to spec/support) as described here.
This was a hard one. But the issue was that I had set force_ssl = true in my application.rb, stupidly, instead of putting it in production.rb and development.rb like a normal person.
I also had set Capybara-webkit's app_host, which, as it turned out, I did not need to do. After removing that, and running capybara-webkit with debug on, I saw that it was trying to redirect from http://localhost:45362/login (or whatever port) to https://localhost:45362/login (note the https!) and that this was causing a DOM 18 security error or whatever, and this was making it choke. I turned off force_ssl and now it works like a champ. Hope this helps you not tear your hair out.
It's definitely best to divide specs up so you have specs pertaining to each aspect of the MVC architecture, but I think there is a slight crossover with controller specs and view specs.
With view specs, you should only be concerned with the view, but with controller specs I still think it would be a good idea to test that the correct view is rendered, and maybe even test the content of the view, although more in-depth testing of the content should take place in the view spec.
Despite this clear article, https://www.relishapp.com/rspec/rspec-rails/v/2-1/docs/controller-specs/render-views, describing how to do this, I just cannot integrate my view and controller specs.
I keep getting the error undefined method 'contain'!
Here's my spec_helper:
# 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 'capybara/rspec'
require 'capybara/rails'
require 'factory_girl_rails'
require 'ap'
def set(factory)
#user = FactoryGirl.create(factory)
end
def sign_up(first_name, last_name, profile_name, email, password)
visit "/"
click_link "Register"
fill_in('First name', with: first_name)
fill_in('Last name', with: last_name)
fill_in('Profile name', with: profile_name)
fill_in('Email', with: email)
fill_in('Password', with: password)
fill_in('Password confirmation', with: password)
click_button 'Sign up'
end
def sign_in(email, password)
visit "/"
click_link "Sign In"
fill_in('Email', with: email)
fill_in('Password', with: password)
click_button 'Sign in'
end
def sign_out
visit "/"
click_link "Sign Out"
end
#Webrat.configure do |config|
# config.mode = :rails
#end
#webrat
require 'capybara/poltergeist'
# Capybara.javascript_driver = :poltergeist
Capybara.javascript_driver = :selenium
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|
# true means 'yes, filter these specs'
config.filter_run_excluding stress: true
# config.current_driver = :webkit
# config.use_transactional_fixtures = false
# config.include Capybara::DSL
DatabaseCleaner.strategy = :truncation
config.after(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
# config.before(:suite) do
# DatabaseCleaner.strategy = :transaction
# DatabaseCleaner.clean_with(:truncation)
# DatabaseCleaner.start
# end
# config.after(:each) do
# DatabaseCleaner.clean
# end
#config.after(:suite) do
# DatabaseCleaner.strategy = :transaction
# DatabaseCleaner.clean_with(:truncation)
# DatabaseCleaner.clean
# end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.include RSpec::Rails::RequestExampleGroup, type: :feature
# 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
I18n.enforce_available_locales = 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
Here's my controller spec:
require "spec_helper"
describe UserFriendshipsController, type: :controller do
render_views
let (:user_1) { FactoryGirl.create(:user_1)}
before {
sign_in user_1
get :index
}
it "renders the :index view" do
response.should render_template(:index)
end
it "view contains expected html" do
# a sanity test more than anything
response.should contain("Welcome to the home page")
end
end
Upon running this spec I get this:
.F
Failures:
1) UserFriendshipsController view contains expected html
Failure/Error: response.should contain("Listing widgets")
NoMethodError:
undefined method `contain' for #<RSpec::Core::ExampleGroup::Nested_1:0x00000008632268>
# ./spec/controllers/user_friendships_spec.rb:18:in `block (2 levels) in <top (required)>'
Finished in 0.1835 seconds
2 examples, 1 failure
Why is this happening? How can I get this to work?
If you look at the relish documentation for the current 2.14 version of Rspec you'll see that they're using match now instead:
expect(response.body).to match /Listing widgets/m
Using the should syntax, this should work:
response.body.should match(/Welcome to the home page/)
Right, it was a very unclear article from Rspec that caused this error. It was using webrat in its example and didn't think to tell you. If anyone else gets here, you can add webrat to your gemfile to use the contain method:
Gemfile
group :test do
gem 'webrat'
end
However, it makes a lot more sense to use rspec's native match method:
expect(response.body).to match /Listing widgets/m
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