使用rake从db / seeds.rb自动加载种子数据

时间:2011-12-05 14:15:01

标签: ruby-on-rails-3 testing rspec rake

我使用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

最好的办法是什么?感谢。

7 个答案:

答案 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)

  1. 复制config / initializers文件夹中的seed.rb文件。所以seed.rb文件将在服务器启动时执行。

  2. 运行以下命令,使用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,种子数据将被清除。