I set up cucumber/rails for my rails project and populated the test database with data, to run tests against it. When I run "rake cucumber" the database gets truncated. I tried to set DatabaseCleaner.strategy to :transaction and nil, but it still gets truncated. I'd prefer not to use database_cleaner at all for now, but its presence is required by cucumber. Here is my "./features/support/env.rb" file:
require 'cucumber/rails'
require 'capybara/cucumber'
Capybara.default_driver = :selenium
ActionController::Base.allow_rescue = false
begin
DatabaseCleaner.strategy = nil
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
Cucumber::Rails::Database.javascript_strategy = :truncation
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
I don't believe there is a strategy that does nothing, but cucumber doesn't need it to run. Possibly you may have to remove it from your env.rb file and any db cleaning in your hooks file.
EDIT:
I was wrong, there is a null strategy. Try:
DatabaseCleaner.strategy = DatabaseCleaner::NullStrategy
or
DatabaseCleaner::Base.new
You need to set both the DatabaseCleaner.strategy and the Cucumber::Rails::Database.javascript_strategy.
Cucumber-rails does not come with a null strategy so you have to make one. This works for me, in env.rb:
DatabaseCleaner.strategy = DatabaseCleaner::NullStrategy
class NullStrategy < Cucumber::Rails::Database::Strategy
def before_js
super DatabaseCleaner::NullStrategy
end
end
Cucumber::Rails::Database.javascript_strategy = NullStrategy
I believe this is the simplest and documented approach.
Cucumber::Rails::Database.autorun_database_cleaner = false
Related
I have a few tests in my suite that absolutely need an empty database to run.
Thing is, rails is automatically loading the fixtures for every test, and I can't seem to find a way to have it not load for this specific test.
I could drop the database before each test, but that's slow and requires all other tests that require fixtures to reload the fixtures afterwards.
Is there any way to have a certain test class (i.e. "NoFixturesTest") not load the fixtures (or unload them), without breaking all other tests?
Thanks!
EDIT:
Thanks to the answer below, I made this:
module DisableFixturesHelper
def self.included(base)
base.setup :setup_drop_db
# Have a unit test double-check that the fixtures are really gone
base.test "0 fixtures not loaded" do
assert_equal 0, Table1.count, "Table1 isn't empty!"
#etc
end
end
# Call to reset the db and therefore disable fixtures during a single unit test
def setup_drop_db
Rails.logger.info { "Dropping database." }
DatabaseCleaner.clean_with :truncation
end
end
And then in the TestCases that require an empty database (no fixtures), I add
include DisableFixturesHelper
The problem with this is that this drops the database once per test, AFTER the fixtures have already been loaded, so it's really slow. It's literally reloading the fixtures before the start of each unit test, just to drop them.
Still, it works.
do you know DatabaseCleaner ???
maybe it can help, you can also define what don't delete
something like:
DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
here is an initializer that I always use:
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.append_after(:each) do
DatabaseCleaner.clean
end
end
I am using a memory sqlite database to run rspec tests. This functions very well. Only when running selenium driven tests (describe "does something", :js => true do) the starting webbrowser gets the error SQLite3::SQLException: no such table: users: SELECT "users".* FROM "users" WHERE ...
WEBrick/1.3.1 (Ruby/2.0.0/2013-02-24) at 127.0.0.1:57827
I am looking for a solution to run selenium driven test while using a in memory database.
Details:
I use ruby on rails 4.0 and the following gems (excerpt)
gem 'sqlite3', '1.3.7'
gem 'rspec-rails', '2.13.0'
gem 'capybara', '~> 2.1.0.beta1'
gem 'selenium-webdriver', '2.35.1'
database.yml
test:
adapter: sqlite3
database: ":memory:"
pool: 5
timeout: 5000
spec_helper.rb
require 'rubygems'
require 'spork'
Spork.prefork do
# snip
load "#{Rails.root.to_s}/db/schema.rb" # set up memory db
RSpec.configure do |config|
config.use_transactional_fixtures = false #using database cleaner
#snip
config.before :suite do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before type: :request do
DatabaseCleaner.strategy = :truncation
end
# Reset so other non-request specs don't have to deal with slow truncation.
config.after type: :request do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before do
DatabaseCleaner.start
ActionMailer::Base.deliveries.clear
end
config.after do
DatabaseCleaner.clean
end
end
end
The problem seems to have something to do that the capybara web server uses its own database connections (as opposed to the connection used by the tests itself), but the in memory database is only available for the one connection which created it.
This question already provided some insights:
(DatabaseError: no such table: django_session) ERROR during Django 1.3 selenium testing
So, how can I make selenium tests memory db compatible?
Thank you very much in advance.
The capybara Readme itself suggests to monkeypatch the ActiveRecord::Basein the spec_helper.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
If you use spork, the last line belongs to the Spork.each_run section.
In this case, you also have to load the schema.rb in Spork.each_run.
This actually works but is advised to use with caution.
Further information see Why not use shared ActiveRecord connections for Rspec + Selenium?
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
due to a heavy growing project I'm running into the trouble that the database rebuild process of cucumber really takes a long time.
Since it is a application where the actual content of the table doesn't matter, I'd like to skip the rebuild process.
Unfortunately wether cucumber nor database_cleaner seem to support this, doesn't they?
My cucumber env settings may be found below
Thanks and many regards,
Joe
ENV["RAILS_ENV"] ||= "cucumber"
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
require 'cucumber/rails/world'
require 'cucumber/rails/active_record'
require 'cucumber/web/tableish'
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
require 'cucumber/rails/capybara_javascript_emulation'
Capybara.default_selector = :css
ActionController::Base.allow_rescue = false
Cucumber::Rails::World.use_transactional_fixtures = false
Capybara.default_driver = :selenium
if defined?(ActiveRecord::Base)
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
rescue LoadError => ignore_if_database_cleaner_not_present
end
end
An easy way to stop database_cleaner from cleaning one of your tables is to configure it like this:
DatabaseCleaner.strategy = :truncation, {:except => %w[states]}
In this example, once the table states is loaded with information, it doesn't clean it.
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