【问题标题】:How to load db:seed data into test database automatically?如何将 db:seed 数据自动加载到测试数据库中?
【发布时间】:2010-12-07 04:24:33
【问题描述】:

我正在尝试使用在 Rails 2.3.4+ 中加载种子数据的新标准方法,db:seed rake 任务。

我正在加载常量数据,这是我的应用程序真正正常运行所必需的。

在测试之前让db:seed 任务运行的最佳方法是什么,以便预先填充数据?

【问题讨论】:

    标签: ruby-on-rails testing seed


    【解决方案1】:

    db:seed rake 任务主要只是加载db/seeds.rb 脚本。因此只需执行该文件即可加载数据。

    load "#{Rails.root}/db/seeds.rb"
    
    # or
    
    Rails.application.load_seed
    

    放置位置取决于您使用的测试框架以及您是希望在每次测试之前加载它还是只在开始时加载一次。您可以将其放入setup 调用或test_helper.rb 文件中。

    【讨论】:

    • 我喜欢简洁,但出于某种原因,将这一行添加到我的 test_helper.rb 对我不起作用,尽管 stackoverflow.com/a/1998520/68210 确实如此。
    • 在较新版本的 Rails 中,您可以这样做:Rails.application.load_seed
    • @Steve,谢谢 - 例如,如果使用 rspec/capybarra,您知道将 Rails.application.load_seed 放在哪里吗?
    • @BKSpureon 我在我的应用程序中加载了很多种子数据,因为它需要特定的数据才能运行,而且工厂太复杂了。我将Rails.application.load_seed 放在我的rails_helper 文件中的require 'rspec/rails' 下方。如果您使用的是 database_cleaner gem - 需要进行一些调整以确保您在每次测试后不会丢失种子数据,您可以在 gem 的文档中找到它自己
    • 在 Rails 5.x 中,我在现有的 require 'rails/test_help' 行之后将此添加到 test/test_helper.rb
    【解决方案2】:

    应该是这样的

    namespace :db do
      namespace :test do
        task :prepare => :environment do
          Rake::Task["db:seed"].invoke
        end
      end
    end
    

    因为如果你有 config.active_record.schema_format = :sql (db:test:clone_structure is) 则不会执行 db:test:load

    【讨论】:

    • 使用--trace 运行 rake 帮助我了解了它是如何工作的。
    • @BookOfGreg 我在我自己创建的 lib/tasks/test_seed.rake 中有它
    • 为什么不只是这个? task 'db:test:prepare' => 'db:seed'
    • 对于 Rails 4.0.0 最终添加 ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test']) 之前 Rake::Task["db:seed"].invoke
    • @CarsonReinke - 因为 db:seed 运行时的环境是 development... 很奇怪。
    【解决方案3】:

    在 lib/tasks/test_seed.rake 中添加类似的内容应该在 db:test:load: 之后调用种子任务:

    namespace :db do
      namespace :test do
        task :load => :environment do
          Rake::Task["db:seed"].invoke
        end
      end
    end
    

    【讨论】:

      【解决方案4】:

      我相信上面的Steve's comment 应该是正确的答案。您可以使用Rails.application.load_seed 将种子数据加载到您的测试环境中。但是,加载这些数据的时间和频率取决于以下几点:

      使用 Minitest

      没有方便的方法在所有测试之前运行此文件一次(请参阅this Github issue)。您需要在每次测试之前加载一次数据,可能在测试文件的设置方法中:

      # test/models/my_model_test.rb
      class LevelTest < ActiveSupport::TestCase
      
        def setup
          Rails.application.load_seed
        end
      
        # tests here...
      
      end
      

      使用 RSpec

      使用 RSpec 的 before(:all) 方法为该模型的所有测试加载种子数据:

      describe MyModel do
        before(:all) do
        Rails.application.load_seed
      end
      
      describe "my model..." do
        # your tests here
      end
      

      希望这会有所帮助。

      【讨论】:

      • 迄今为止的最佳答案
      • 我做了类似的事情,除了我在before(:suite)而不是before(:all)中调用它。发布了一个单独的答案以包含格式化的代码。
      • 这是正确的答案,至少对于 MiniTest 而言。将其添加到 test_helper.rb 会导致种子文件多次运行,可能会由于重复键而导致错误。
      【解决方案5】:

      我们正在调用 db:seed 作为 db:test:prepare 的一部分,其中:

      Rake::Task["db:seed"].invoke

      这样,种子数据在整个测试运行中加载一次,而不是每个测试类一次。

      【讨论】:

      • 您是否为此创建了一个新的 db:test:prepare 任务?可以发一下代码吗?
      【解决方案6】:

      Rake::Task["db:seed"].invoke 添加到db:test:prepare rake 任务对我不起作用。如果我用rake db:test:prepare准备数据库,然后在测试环境中进入控制台,我所有的种子都在那里。但是,种子在我的测试之间没有持续存在。

      不过,在我的设置方法中添加 load "#{Rails.root}/db/seeds.rb" 效果很好。

      我想让这些种子自动加载并持续存在,但我还没有找到方法!

      【讨论】:

        【解决方案7】:

        对于使用种子库的用户,它会改变种子的加载方式,因此您可能不能/不想使用此处提供的load ... 解决方案。

        只是将Rake::Task['db:seed'].invoke 放入 test_helper 会导致:

        Don't know how to build task 'db:seed' (RuntimeError)
        

        但是当我们在此之前添加 load_tasks 时,它起作用了:

        MyApp::Application.load_tasks
        Rake::Task['db:seed'].invoke
        

        【讨论】:

          【解决方案8】:

          基于 Matt 的回答,如果采用这种方式,我建议在 rspec_helper.rbbefore(:suite) 块中调用 Rails.application.load_seed,而不是在任何文件中的 before(:all) 块中调用。这样一来,整个测试套件只调用一次种子代码,而不是每组测试一次。

          rspec_helper.rb:

          RSpec.configure do |config|
            ...
            config.before(:suite) do
              Rails.application.load_seed
            end
            ...
          end
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-28
            • 2022-01-03
            • 2015-05-01
            • 1970-01-01
            相关资源
            最近更新 更多