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

发布于 2024-12-19 14:36:50 字数 1551 浏览 0 评论 0原文

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

最好的方法是什么?谢谢。

I'm using rails-rspec gem and I have several specs (models, controllers, etc). When I run:

bundle exec rake

everything is tested. However, I would like to improve my specs by seeding some data (from db/seeds.rb) just after the database is created (in test environment).

My spec/spec_helper.rb file looks like this:

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

What could do the best way to do so? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

俯瞰星空 2024-12-26 14:36:51

我将 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 即可。

I set up my rake spec task to automatically load db/seeds.rb, so I depend on that for setting up the database for a first run. Add this to your Rakefile:

task :spec     => "db:seed"
task :cucumber => "db:seed"

Then, on subsequent runs I just call rspec spec directly to skip the seed step and avoid unnecessary reloading. I configure database cleaner to ignore the seed tables like this:

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

For scenarios that need committed data, I can add:

describe "commit for real", use_transactions: false do
  # ...
end

This will truncate everything after the example runs, except the seed tables. It's assumed that you never write anything to the seed tables! This is generally a safe assumption, since seed data is typically static.

For all other normal scenarios, I depend on transactions to roll back any inserted records. The database is returned to the original state, with the data in the seed tables intact. It's safe to write to the seed tables here if you need to.

To rebuild the seed tables, you just need to run rake spec again.

温折酒 2024-12-26 14:36:51

要在 rspec 中加载种子,您​​需要在数据库清理后将其添加到 confg.before(:suite) 中
规范助手

config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
  load "#{Rails.root}/db/seeds.rb" 
end

To load seeds in rspec you need to add it after database cleanup in confg.before(:suite) in
spec_helper

config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
  load "#{Rails.root}/db/seeds.rb" 
end
爱情眠于流年 2024-12-26 14:36:51

Rails 4.2.0RSpec 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

In Rails 4.2.0 and RSpec 3.x, this is how my rails_helper.rb looks.

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
我做我的改变 2024-12-26 14:36:51
  1. 将seed.rb文件复制到config/initializers文件夹中。这样seed.rb文件将在服务器启动时执行。

  2. 运行以下命令以使用 Seed.rb 数据填充测试数据库

    RAILS_ENV=test rake db:seed

  1. copy the seed.rb file inside the config/initializers folder.So seed.rb file will be executed on server start.

  2. Run the below command to fill the test db with the seed.rb data

    RAILS_ENV=test rake db:seed

别想她 2024-12-26 14:36:51

使用

config.before(:each) do
  Rails.application.load_seed # loading seeds
end

我认为我们应该在运行所有示例之前

as before(:all) 运行该块一次。因此,如果我们在:all之前使用,种子数据将被清除。

I think we should use

config.before(:each) do
  Rails.application.load_seed # loading seeds
end

as before(:all) runs the block one time before all of the examples are run.

So if we use before :all, the seed data will be cleared.

微暖i 2024-12-26 14:36:50

坏主意!永远、永远不要为您的测试数据库添加种子。使用工厂在每个测试中创建该测试通过所需的记录。播种测试数据库将使您的测试不太可靠,因为您将做出许多测试中未明确说明的假设。

Bad idea! Never, ever, seed your test database. Use factories to create, within each test, only the records necessary for that test to pass. Seeding the test database will make your tests less reliable, because you'll be making lots of assumptions that aren't explicitly stated in your tests.

奢欲 2024-12-26 14:36:50

根据种子文件的配置方式,您可能只能从 before(:each)before(:all) 块加载/运行它:

load Rails.root + "db/seeds.rb" 

Depending on how your seed file is configured, you might just be able to load/run it from a before(:each) or before(:all) block:

load Rails.root + "db/seeds.rb" 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文