Spork, RSpec and database_cleaner destroying development database - ruby-on-rails-3

I have the following spec_helper.rb file in my Rails 3.1 application. I am using Spork to load the environment faster for testing. All my tests worked prior to adding Spork to the mix. After adding spork, the test database was not getting properly cleared between test runs which threw off some of my expectations.
Following other instructions, I added database_cleaner to the mix with the code listed below; however, now, the development database is getting cleaned up as well as the test database. The ENV["RAILS_ENV"] call is returning test during this call.
Is there a way to explicitly limit the call for DatabaseCleaner.clean_with(:truncation) to only affect the test database?
require 'rubygems'
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda/matchers/integrations/rspec'
require 'database_cleaner'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :mocha
config.formatter = 'documentation'
config.use_transactional_fixtures = true
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
end
Spork.each_run do
FactoryGirl.reload
end
Update: Here is my database.yml file
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Also, I have worked around the basic problem by moving the clean_with call into the before(:each) section, but this slows down the test runs significantly.

Have you tried to move ENV["RAILS_ENV"] ||= 'test' out of the Spork.prefork block?
Are you sure that Spork caused your DB got uncleaned? If you're using RSpec's transactional fixtures, the only thing that could lead to such thing is using factories within before(:all) block. You can clean up data in after(:all) block and get rid of DatabaseCleaner.
BTW, if you're using truncation strategy, there's no need to run DatabaseCleaner.start.

Is your RAILS_ENV explicitly set to "development"? If so, the default spec_helper will run the tests against the development DB. If you run a test from inside vim, or run rspec on the command-line, then it'll run the test against your development DB.
When I'm forced to use database_cleaner, I like to explicitly set RAILS_ENV to test in spec_helper to protect my development DB. Any time you're using something other than transactional fixtures, this is probably a good idea.
I note that you're using both transactional fixtures and database_cleaner. You don't need database_cleaner at all if your DB supports transactions. If you're using Mongo, or you are running capybara-webkit tests, then you'll need database_cleaner, and will want to disable transactional fixtures.

Related

Capybara selenium xvfb throwing end of file error after recent update of Ubuntu 16.04

Currently in my Ruby on Rails application cucumber test are being run with the capybara gem and using selenium.
Recently after a system update to Ubuntu 16.04 the tests started failing with EOFError: end of file reached errors
Additionally, it also occasionally includes the following error.
session not created exception
from unknown error: Runtime.executionContextCreated has invalid 'context': {"auxData": "frameId":"14314.1","isDefault":true},"id":1,"name":"","origin":"://"}
(Session info: chrome=54.0.2840.59)
(Driver info: chromedriver=2.21.371461 (633e689b520b25f3e264a2ede6b74ccc23cb636a),platform=Linux 4.4.0-43-generic x86_64) (Selenium::WebDriver::Error::SessionNotCreatedError)
This question also refers to something similar but with minitest.
This what I believe to be the relevant part of the capybara env.rb file:
require 'cucumber/rails'
require 'capybara'
require 'capybara/cucumber'
require 'capybara-screenshot'
require 'capybara-screenshot/cucumber'
require 'rails/test_help'
require 'minitest/rails'
require 'mocha/mini_test'
require 'headless'
require 'selenium-webdriver'
require 'rack_session_access/capybara'
require 'webmock/cucumber'
WebMock.allow_net_connect!
include Sprig::Helpers
ActionController::Base.allow_rescue = false
Dir.mkdir('test_result') unless File.exist?('test_result')
# Remove/comment out the lines below if your app doesn't have a database.
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
begin
DatabaseCleaner.strategy = :truncation, { only: [] }
DatabaseCleaner.clean_with :truncation, { only: [] }
rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
Capybara.register_driver :selenium do |app|
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 15
Capybara::Selenium::Driver.new(app, browser: :chrome, http_client: client)
end
Capybara.default_driver = :selenium
Capybara.javascript_driver = :selenium
Capybara.raise_server_errors = true
Capybara.default_selector = :css
Capybara.default_max_wait_time = 15
Capybara.save_and_open_page_path = 'tmp/capybara'
I've looked over at a thread in the capybara-webkit gem that looks related, but I'm not actually using webkit.
Any help would be appreciated.
Turns out I'm using a gem called chromedriver-helper that was using rbenv to override the version of chromedriver that was actually being used by capybara and selenium to run the tests. The gem readme said to try running chromedriver-update in the context of the rails app, which cleared everything up.

How do I configure Capybara to work with Poltergeist?

I have an RSpec integration test that needs to execute some JavaScript. I've included Poltergeist and installed PhantomJS, but whenever I run the example, I get this error:
Failure/Error: page.execute_script("$('form')[0].submit();")
Capybara::NotSupportedByDriverError:
Capybara::Driver::Base#execute_script
The spec is:
require 'spec_helper'
describe "Signup", :type => :feature do
describe "workflow" do
it "ensures entry of contact information" do
visit 'signup/action'
# snip - use Capybara to fill out form elements
page.execute_script("$('form')[0].submit();")
page.should have_content("Name can't be blank")
page.should have_content("Email can't be blank")
# snip - use Capybara to fill out more form elements
page.execute_script("$('form')[0].submit();")
page.should have_content("Next page")
end
end
end
I think the problem is that I'm not sure how to indicate that Capybara should use Poltergeist as its JavaScript driver. The Poltergeist documentation says:
Installation
Add poltergeist to your Gemfile, and in your test setup add:
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
But it doesn't say which file specifically it should go into. It also says:
Customization
You can customize the way that Capybara sets up Poltegeist via the following code in your test setup:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, options)
end
But it's not clear to me if or when I would need to include this in my tests. And again, I'm not sure where to put it if I need to.
What am I missing?
Where do I need to put the configuration for Capybara and Poltergiest, and what exactly does it need to say (or how can I determine that for myself)?
Is there a step or piece of configuration that I missed?
Try putting js: true in your describe line. I know i had to do that for feature specs on an app at work:
describe "Signup", :type => :feature, :js => true do
I don't see any other configuration for it. Was a while ago when I set it up :)
You can just call the Capybara driver config methods once before your RSpec.configure block:
Capybara.default_selector = :css
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, :window_size => [1920, 1080], :phantomjs_logger => nil)
end
Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
Also be sure to use truncation not transaction with database cleaner. Poltergeist runs on a separate thread, so you'll likely have weird db issues if you use transactional.
Edit
Ah the js true thing is mentioned under here: https://github.com/jnicklas/capybara#using-capybara-with-rspec in the capybara readme.

Run all models tests using rake task

Trying to use a rake task to run only tests in the test/models directory. Using minitest.
I have a rake task that will run all test
require "rake/testtask"
Rake::TestTask.new(:test => "db:test:prepare") do |t|
t.libs << "test"
t.pattern = "test/**/*_test.rb"
end
task :default => :test
Then, running 'rake' hits the default and runs all tests. I want to write a second rake task that would only run tests in the models directory (test/models/).
I played around with this existing TestTask by simply changing
t.pattern = "test/**/*_test.rb"
to
t.pattern = "test/models/*_test.rb"
but, it seems to still run all the tests...not just models. Strange?
QUESTIONS
How can I accomplish this? How to I need to name a second TestTask that will run only models, and how do I tell rake to run that test instead of the default :test?
The pattern you are looking for is "test/models/**/*_test.rb". The "**" will match subdirectories as well.
If you are using minitest-rails then you have lots of tasks added for you. To run all Model tests run:
rake minitest:models
To see all the rake tasks creates for you, run:
rake -T
As usual, the answer was quite simple. Just took a bit of digging around. Make sure you have the following in your application.rb (inside the module).
config.generators do |g|
g.fixture_replacement :factory_girl # if your using factory_girl
g.test_framework :mini_test, :spec => true, :fixture => false
end
Then you have access to minitests built in commands. The one I was looking for is as simple
rake minitest:models
Booya!

Rake::TestTask not running minitest files

I'm using minitest for one of my projects, and I can't seem to get the Rake TestTask to actually run the files.
require 'rake'
require 'rake/testtask'
task :mytest do
Rake::TestTask.new do |t|
t.test_files = Dir.glob('test/model/*_test.rb')
t.verbose = true
puts t.inspect
puts '-------------------------------------'
end
end
when I run this task rake mytest, I get the following output :
projects#webdev-local:/home/projects/framework# rake mytest
#<Rake::TestTask:0x00000001775050 #name=:test, #libs=["lib"], #pattern=nil,
#options=nil, #test_files=["test/model/page_model_test.rb",
"test/model/widget_model_test.rb"], #verbose=true, #warning=false, #loader=:rake,
#ruby_opts=[]>
-------------------------------------
As you can see, The task finds the files, but it never actually runs them. How can I get it to run these files?
Using Rails 3.2.8 and ruby 1.9.3
So, two things you might want to check:
1) Make sure you're using the minitest-rails gem
It adds a lot of the test runner tasks we want and need.
https://github.com/blowmage/minitest-rails
2) The contents of your minitest_helper.rb file (a la spec_helper.rb)
You should have some kind of helper file that you're requiring in all your tests. Make sure it looks something like this:
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require "minitest/autorun"
require "minitest/rails"
class ActiveSupport::TestCase
fixtures :all
end
Now that you have that setup, you can run all the tests as follows:
bundle exec rake test
bundle exec rake minitest # alias for test
bundle exec rake minitest:models
# ... etc ...

rspec returns "PG::Error: ERROR: relation "table_name" does not exist"

Environment is REE(2011.12) on rvm, rspec 2.8.0, rails 3.0.6, and pg 0.13.2. Using PostgreSQL 8.3.17 on CentOS 5.6. The db:migrate have work correctly. But rspec have got following error.
1) ApiController articles OK
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::StatementInvalid:
PG::Error: ERROR: relation "table_name" does not exist
: DELETE FROM "table_name"
I'm updating my project from rails 2.3.5 with rspec 1.x series to rails 3.0 with rspec2. Copied all rspec tests, and I have merged old spec_helper.rb and new one(It was generated rails g rspec:install).
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
end
I read similar question about this error.So I tried rake db:test:prepare or rake db:test:load, But It's not resolve. Do you have any idea?
It looks like the test hasn't run on test database... How do I do? :(
I've run into this in two instances (updated 6/13/2012):
First:
I haven't yet migrated my test database...
rake db:migrate
...which you need to do before both db:test:prepare and db:test:load.
When you invoke rspec it should prepare and load your database for you anyway. You shouldn't have to do that by hand.
Second:
A typo in my migration. I accidentally reversed my table and column names in the parameter list.
A migration on a Rails 3.1 project:
def change
add_column :had_import_errors, :studies, :boolean, :default => false
add_column :import_data_cache, :studies, :text
end
...which is wrong, because has_import_errors and import_data_cache are my column names, and they therefore should come second, not first.
The correct migration, with the table name first was:
def change
add_column :studies, :had_import_errors, :boolean, :default => false
add_column :studies, :import_data_cache, :text
end
This usually happens when you have rspec running while migrating (usually via guard). A simple solution is to quit guard, do the migration and restart guard.
It typically indicates that there is another open PostgreSql connection. To bubble up the right error try % rake db:test:prepare
Running test prepare showed the following below and when the open connection (PGAdmin in my case) was closed the issue was resolved.
rake aborted!
PG::Error: ERROR: database "xyz_test" is being accessed by other users
DETAIL: There are 1 other session(s) using the database.
: DROP DATABASE IF EXISTS "xyz_test"
Tasks: TOP => db:test:load => db:test:purge
(See full trace by running task with --trace)
Just hit this same error, nothing worked but dropping and re-creating the database, this fixed it for me.
rake db:drop db:create db:migrate