我使用rails-rspec
gem,我有几个规格(型号,控制器等)。我跑的时候:
bundle exec rake
一切都经过测试。但是,我想通过在创建数据库之后(在测试环境中)播种一些数据(来自db / seeds.rb)来改进我的规范。
我的spec / spec_helper.rb文件如下所示:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'ruby-debug'
# 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.mock_with :rspec
# 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
config.include SpecHelper
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
stub_xmpp_rest_client!
end
config.after(:each) do
DatabaseCleaner.clean
end
config.include Devise::TestHelpers, :type => :controller
config.include Delorean
config.after(:each) { back_to_the_present }
config.include Factory::Syntax::Methods
config.extend ControllerMacros, :type => :controller
end
最好的办法是什么?感谢。
答案 0 :(得分:44)
糟糕的主意!从来没有,为您的测试数据库提供种子。使用工厂在每个测试中创建仅该测试通过所需的记录。播种测试数据库将使您的测试不太可靠,因为您将做出许多未在测试中明确说明的假设。
答案 1 :(得分:29)
根据您的种子文件的配置方式,您可能只能从before(:each)
或before(:all)
块加载/运行它:
load Rails.root + "db/seeds.rb"
答案 2 :(得分:12)
我设置我的rake spec
任务以自动加载db / seeds.rb,所以我依赖它来设置数据库以进行第一次运行。将其添加到您的Rakefile:
task :spec => "db:seed"
task :cucumber => "db:seed"
然后,在后续运行中,我只是直接调用rspec spec
来跳过种子步骤并避免不必要的重新加载。我配置数据库清理程序忽略种子表,如下所示:
RSpec.configure do |config|
config.add_setting(:seed_tables)
config.seed_tables = %w(countries roles product_types)
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation, except: config.seed_tables)
end
config.around(:each) do |example|
if example.metadata[:no_transactions]
DatabaseCleaner.strategy = :truncation, {except: config.seed_tables}
else
DatabaseCleaner.strategy = :transaction
end
DatabaseCleaner.start
example.run
DatabaseCleaner.clean
end
end
对于需要提交数据的方案,我可以添加:
describe "commit for real", use_transactions: false do
# ...
end
除了种子表之外,这将截断示例运行后的所有内容。 假设你从不向种子表写任何东西!这通常是一个安全的假设,因为种子数据通常是静态的。
对于所有其他正常情况,我依赖事务来回滚任何插入的记录。数据库返回到原始状态,种子表中的数据保持不变。如果需要,可以在此处写入种子表,这是安全的。
要重建种子表,只需再次运行rake spec
。
答案 3 :(得分:7)
要在rspec中加载种子,您需要在confg.before(:suite)中的数据库清理后添加它 spec_helper
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
load "#{Rails.root}/db/seeds.rb"
end
答案 4 :(得分:7)
在 Rails 4.2.0 和 RSpec 3.x 中,这就是我的rails_helper.rb的外观。
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
# 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
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
config.before(:all) do
Rails.application.load_seed # loading seeds
end
end
答案 5 :(得分:0)
复制config / initializers文件夹中的seed.rb文件。所以seed.rb文件将在服务器启动时执行。
运行以下命令,使用seed.rb数据填充测试数据库
RAILS_ENV =测试rake db:seed
答案 6 :(得分:-1)
我认为我们应该使用
config.before(:each) do
Rails.application.load_seed # loading seeds
end
为before(:all) runs the block one time before all of the examples are run.
因此,如果我们使用before :all
,种子数据将被清除。