I have the following code:
RSpec.configure do |config|
# ...
config.before(:each, billy: true) do
Capybara.current_driver = :poltergeist_billy
end
config.after(:each, billy: true) do
Capybara.use_default_driver
end
end
So every spec tagged with :billy is executed with :poltergeist_billy capybara driver.
But I have plenty of drivers in my application. I want to restore previously used driver, not just to fall back to default when I execute billy-test.
What's the best way to restore the driver and where should I keep this variable?
Related
I have a rich frontend in my application. Some of my tests not works well with poltergeist, because of animations and AJAX requests, but works fine with selenium.
How can i use them together in one project and in one test session?
If you're using the standard RSpec configuration with Capybara (require 'capybara/rspec') then you can override the normal driver that would be used for a given test with :driver metadata
it "should do something", driver: :selenium do
# will use the selenium driver for this test
end
it "should do something else", driver: :poltergeist do
# will use the poltergeist driver for this test
end
that could also be specified on the enclosing feature if you want the whole feature to use a specific driver
feature "blah balh", driver: :selenium do
# all scenarios here would use the selenium driver unless overridden with their own :driver metadata
I found solution.
Created macros in spec/support/selenium_macros.rb:
module SeleniumMacros
def use_selenium_webdriver
before(:all) do
Capybara.javascript_driver = :selenium
Capybara.current_driver = :selenium
end
after(:all) do
Capybara.current_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
end
end
end
spec/rails_helper.rb
RSpec.configure do |config|
config.extend SeleniumMacros, type: :feature # add macros for acceptance tests
using example
spec/features/example_feature_spec.rb
feature 'Add files to question' do
use_selenium_webdriver
this feature will be work with selenium, after it will be executed it activates poltergeist webdriver.
P.S. Sorry for my english.
I would like to switch to webkit_billy (the Javascript driver of Puffing Billy gem) only in certain tests. I want to be able to use:
describe "xxx", billy: true do
end
This should signal to RSpec that I want to switch to puffing billy driver.
I wrote this in spec_helper.rb but it's not working:
config.before(:each) do |example|
if [:billy].include? example.metadata[:type]
Capybara.current_driver = :webkit_billy
Capybara.javascript_driver = :webkit_billy
else
Capybara.current_driver = :webkit
Capybara.javascript_driver = :webkit
end
end
Capybara.javascript_driver is only used (with normal configuration) when js: true metadata is added to the test so there is no need to keep resetting the value of javascript_driver to :webkit_billy since all that would do is affect any further tests with the js metadata. You can see the default behavior implementation (when you require capybara/rspec) here
What this does is initially set the driver for the test to whatever Capybara.default_driver is, then if the js metadata exists it sets the driver to the value of Capybara.javascript_driver, and then if driver metadata exists it sets it to that - ie. driver metadata takes priority over 'js' and if nothing you just get default_driver. What this means is without any extra additions you could just specify driver: :webkit_billy on a test and get :webkit_billy used for that test.
To add your desired behavior of being able to specify billy: true you just need
RSpec.configure do |config|
config.before(:each, billy: true) do
Capybara.current_driver = :webkit_billy
end
end
somewhere after you've required 'capybara/rspec' but before your database cleaner configuration is defined. Then set Capybara.default_driver to whatever driver you want to use when no metadata is specified, and Capybara.javascript_driver to whatever driver you want to use when js metadata is specified. So - if you wanted to always use the :webkit driver (other than when billy is specified) set Capybara.default_driver = :webkit and you never need to specify js: true , but can always make specific tests use rack_test by adding driver: :rack_test metadata to a specific test.
Note: This supposes you are using the recommended database_cleaner config - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example - which changes database strategy based on the actual driver being used and not just based on the presence of the js metadata.
how about you try this:
config.before(:each, billy: true) do |example|
Capybara.current_driver = :webkit_billy
Capybara.javascript_driver = :webkit_billy
end
or to go your current approach, you'd do:
config.before(:each) do |example|
if example.metadata[:billy] # this should either be true or nil
Capybara.current_driver = :webkit_billy
Capybara.javascript_driver = :webkit_billy
else
Capybara.current_driver = :webkit
Capybara.javascript_driver = :webkit
end
end
The database is not being cleaned after each integration test. The value stays in the database.
Is there an option I should have to make this happen?
Thanks
I think https://github.com/bmabey/database_cleaner is what you need.
For anyone using before(:all) hooks, be aware that these hooks are executed before the transaction associated to the fixture is opened. This means that any data created by before(:all) hooks will not be rolled back by transactional fixtures. You can read more in the RSpec documentation.
I just wanted to mention this because I was bit by it and my initial instinct was to jump to Database Cleaner (which wound up not being needed and eventually not working).
How do I prepare test database(s) for Rails rspec tests without running rake spec?
My answer there might be of interest to you. it's a nice solution. For your case, you would probably need something like
config.after :each do
ActiveRecord::Base.subclasses.each(&:delete_all)
end
Look here for a tutorial: http://railscasts.com/episodes/257-request-specs-and-capybara
It describes Database Cleaner besides Rspec and Capybara
You want DatabaseCleaner, but you may find that the :truncation strategy is a bit too slow to run all the time. It's really only necessary for integration tests, so you can do this:
# spec/spec_helper.rb
require 'database_cleaner'
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do |group|
# The strategy needs to be set before we call DatabaseCleaner.start
case group.example.metadata[:type]
when :feature
DatabaseCleaner.strategy = :truncation
else
DatabaseCleaner.strategy = :transaction
end
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
# spec/features/your_feature_spec.rb
require 'spec_helper'
describe "An integration test", :type => :feature do
end
# spec/model/your_model_spec.rb
require 'spec_helper'
describe "A unit test" do
end
Obviously, this only applies if you're doing integration tests with RSpec directly vs. doing them with Cucumber.
There are two ways to accomplish this:
Configure transactional examples for each individual test.
Configure transactional examples for all the tests.
If you opt for option 1: At the top of the spec file, after:
require 'spec_helper'
Add:
RSpec.configure {|c| c.use_transactional_examples = true }
That will roll back the transactions after each example.
2.If you want to configure it globally, then, in the spec_helper.rb
RSpec.configure do |config|
...
config.use_transactional_examples = true # Add this
...
end
I'm running rails 3.0.3 and using rspec-rails 2.4.1 with a postgresql database. Whenever I run my RSpec tests, the data remains at the end. Does anyone know how to get rails or rspec to wipe the test environment's data between each use?
Please tell me if there's any further information that could make answering my question easier.
Thanks!Tristan
Install the database_cleaner gem and then add this to your spec_helper.rb.
Spec::Runner.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Use transactional examples to rollback the data after every test run
RSpec.configure do |config|
config.use_transactional_examples = true
end
You don't need any extra gem in order to clean your test DB between runs. In your spec_helper.rb file, configure rspec as follows:
RSpec.configure do |c|
c.around(:each) do |example|
ActiveRecord::Base.connection.transaction do
example.run
raise ActiveRecord::Rollback
end
end
end
Another possibility, that I just put myself through, is using the wrong before block.
I accidentally set a before block as an all instead of an each:
before :all do
user = FactoryGirl.create(:user)
sign_in user
end
This caused the user to stick around in the database for the entire rspec run, which caused validation collisions.
Instead, the before should be an each so that everything is kept clean through the rspec run:
before :each do
user = FactoryGirl.create(:user)
sign_in user
end
If you've made this mistake, then you will probably need to manually clean up your test database before things go back to normal. The simplest way to do that is probably to truncate each of the tables (aside from schema_migrations).
I am using Cucumber with Selenium, FixtureReplacement and DatabaseCleaner.
Funnily enough, my data I created with FixtureReplacement is not accessible from my tests.
I have added an own rails environment for selenium and I am using an own profile for my enhanced selenium features.
My cucumber setup for the selenium profile is:
Webrat.configure do |config|
config.mode = :selenium
config.application_environment = :selenium
end
Cucumber::Rails::World.use_transactional_fixtures = false
require "database_cleaner"
# Clean the database once when starting
DatabaseCleaner.clean_with :truncation
DatabaseCleaner.strategy = :truncation
Before do
DatabaseCleaner.start
include FixtureReplacement
end
After do
DatabaseCleaner.clean
end
# this is necessary to have webrat "wait_for" the response body to be available
# when writing steps that match against the response body returned by selenium
World(Webrat::Selenium::Matchers)
FixtureReplacement works well, I have tested it in the Rails console.
I am running my selenium features with:
RAILS_ENV=selenium cucumber -p selenium features/enhanced/test.feature
Does anybody know a solution to this problem?
Best regards
I wonder if you are using Database Cleaner correctly? In my env.rb, I am using it like this:
Before do
require 'database_cleaner'
require 'database_cleaner/cucumber'
DatabaseCleaner.strategy = :truncation
end
This works for me when using Factory Girl.
This had nothing to do with Fixtures. I thought I cannot access my data, because I couldn't login.
The following fixed it:
Cucumber + selenium fails randomly