R_G R_G - 6 months ago 58
Ruby Question

Every RSpec test run requires rake db:test:prepare or equivalent using Rails 4.2.5

Using Ruby 2.0.0, Rails 4.2.5, RSpec 3.4.4, Shoulda-matcher 3.1.1, Database_cleaner 1.4.0, PostgreSQL 9.4.5.

For every rspec (or rake spec) I have to prepare the test database. If I don't, I receive the "Migrations are pending." message. Everything I read tells me this is not right given Rails 4.1+. I've taken every corrective action that I can find to no avail.

Preparing the test database means I either use "rake db:test:prepare", which is deprecated, or a series of "rake db:drop/create/migrate RAILS_ENV=test". Either works. A simple migrate after a test does not work as it tries to recreate all the tables though they exist. None of these problems exist in development or on Heroku production as all migrations are processed and work fine.

Rails_helper.rb contains the command "ActiveRecord::Migration.maintain_test_schema!" which should control this problem. In actual fact, that command is the one that identifies that a migration is required and throws the "Migrations are pending." message. I tried including the command "ActiveRecord::Migrator.migrate(File.join(Rails.root, 'db/migrate'))" to check and force a migration if required, but that is the same as running a new migrate and causes the problem I mentioned about recreating existing tables.

I did use "rails generate rspec:install" to rebuild .rspec, spec_helper.rb and rails_helper.rb and then update the new files to try to solve the problem. I also migrated all of my configurations over to rails_helper.rb. spec_helper.rb is all comments.

The failure is as follows:

rake spec
Running rails_helper.rb
D:/BitNami/rubystack-2.0.0-38/ruby/lib/ruby/gems/2.0.0/gems/activerecord-4.2.5/lib/active_record/migration.rb:392:in `check_pending!': (ActiveRecord::PendingMigrationError)
Migrations are pending. To resolve this issue, run:
bin/rake db:migrate RAILS_ENV=test


.rspec

--color
--format documentation
--require rails_helper


rails_helper.rb

# This file is copied to spec/ when you run 'rails generate rspec:install'
puts "Running rails_helper.rb"
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)

abort("The Rails environment is not running in test mode!") unless Rails.env.test?

require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
require 'shoulda/matchers'

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f; puts "File #{f}" }

ActiveRecord::Migration.maintain_test_schema!
#ActiveRecord::Migrator.migrate(File.join(Rails.root, 'db/migrate'))

RSpec.configure do |config|
config.extend ControllerMacros, type: :controller
config.include JsonSpec::Helpers
config.render_views # Intended to ensure that views are processed

config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

# ## Mock Framework
config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr

# 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"

# rspec-rails 3 will no longer automatically infer an example group's spec type
# from the file location. You can explicitly opt-in to this feature using this
# snippet:
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")

# Sorcery RSpec configuration
# config.include Sorcery::TestHelpers::Rails::Controller, type: [:controller]
# config.include Sorcery::TestHelpers::Rails::Integration, type: [:feature]
config.include Sorcery::TestHelpers::Rails

# FactoryGirl RSpec configuration
config.include FactoryGirl::Syntax::Methods

end


Gemfile

source 'https://rubygems.org'
ruby '2.0.0'
gem 'rails', '4.2.5'
gem 'sprockets', '3.4.0'
gem 'sprockets-rails', '2.3.3'
gem 'sass', '3.4.19'
gem 'sass-rails', '5.0.4'
gem 'uglifier', '2.7.1'
gem 'coffee-rails', '4.1.0'
gem 'turbolinks', '2.5.3'
gem 'jquery-turbolinks', '2.1.0'
gem 'jbuilder', '2.2.13'
gem 'will_paginate', '~> 3.0.7'
gem 'bootstrap-sass', '3.3.5.1'
gem 'figaro', '1.1.1'
gem 'pg', '0.18.1'
gem 'simple_form', '3.1.0.rc2'
gem 'sorcery', '0.9.1'
gem 'rolify', '4.0.0'
gem 'acts_as_tenant', '0.3.9'
gem 'jquery-datatables-rails', '3.3.0'
gem 'jquery-rails', '4.0.4'
gem 'jquery-ui-rails', '5.0.5'
gem 'lodash-rails', '3.7.0'
gem 'logging', '2.0.0'
gem 'smarter_csv', '1.0.19'
gem 'addressable', '2.3.8'
gem 'delayed_job', '4.0.6'
gem 'delayed_job_active_record', '4.0.3'
gem 'better_delayed_job_web', '1.3.12'
gem 'roo', '2.0.1'
gem 'roo-xls', '1.0.0'
gem 'font-awesome-sass', '4.3.2.1'
gem 'autoprefixer-rails', '5.2.0'
gem 'twilio-ruby', '4.7.0'
gem 'exception_notification', '4.1.1'
gem 'exception_notification-rake', '0.2.1'
gem 'tzinfo-data'
gem 'responders', '2.1.0'
gem 'rubyzip', '1.1.7'
gem 'htmlentities', '4.3.3'
gem 'axlsx', '2.1.0.pre'
gem 'axlsx_rails', '0.3.0'
gem 'acts_as_xlsx', '1.0.6'
gem 'spreadsheet', '1.0.3'
gem 'redis', '3.2.1'
gem 'aws-sdk', '2.1.35'
gem 'aws-sdk-core', '2.1.35'
gem 'aws-sdk-resources', '2.1.35'
gem 'phony', '2.15.10'
gem 'phony_rails', '0.12.11'
gem 'ranger', '1.1.0'
gem 'execjs', '2.6.0'
gem 'paloma', '4.2.1'
gem 'rabl-rails', '0.4.2'
gem 'gon', '6.0.1'
group :production, :staging do
platforms :ruby do # Linux
gem 'unicorn', '4.9.0'
end
platforms :mswin do # Windows
gem 'passenger', '5.0.8'
end
gem 'rails_12factor', '0.0.3' # For Heroku
end
group :development do
gem 'brakeman', require: false
gem 'web-console', '2.1.3'
gem 'bullet', '4.14.7'
gem 'better_errors', '2.1.1'
gem 'binding_of_caller', '0.7.2'
gem 'quiet_assets', '1.1.0'
gem 'rails_layout', '1.0.26'
gem 'meta_request', '0.4.0'
gem 'coffee-rails-source-maps', '1.4.0'
end
group :development, :test do
gem 'thin', '1.6.3'
gem 'letter_opener', '1.3.0'
gem 'factory_girl_rails', '4.5.0'
gem 'rspec-core', '3.4.4'
gem 'rspec-rails','3.4.2'
gem 'rspec-collection_matchers', "1.1.2"
end
group :test do
gem 'database_cleaner', '1.4.0'
gem 'email_spec', '1.6.0'
gem 'shoulda-matchers', '3.1.1', require: false
gem 'shoulda-callback-matchers', '1.1.3'
gem 'mocha', '1.1.0'
gem 'json_spec', '1.1.4'
gem 'pry', '0.10.1'
gem 'capybara', '2.4.4'
gem "faker", "~> 1.4.3"
gem "forgery", "~> 0.6.0"
gem "launchy", "~> 2.4.3"
gem "selenium-webdriver", "~> 2.53.0"
end


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

Answer

This is apparently a known issue with Database Cleaner in version 1.4.0 where the schema_migrations table is cleaned along with the rest of the database: https://github.com/DatabaseCleaner/database_cleaner/issues/317.

The schema_migrations table is used internally by Rails to track migration history. Thus, when it gets cleared Rails thinks that none of your migrations have been run. The simple fix is to upgrade Database Cleaner to a version newer than 1.4.0.

Comments