代码之家  ›  专栏  ›  技术社区  ›  aaron

防止Rails测试删除种子数据

  •  13
  • aaron  · 技术社区  · 15 年前

    我正在使用seeds.rb填充一些状态模型引用数据:

    State.create :name => 'Alabama', :abbreviation => 'AL'
    State.create :name => 'Alaska', :abbreviation => 'AK'
    # ...
    

    虽然我没有使用状态设备(因为它是种子数据,所以我认为完全为了测试而复制它并不干燥),但是Rails测试框架在测试期间似乎删除了所有的状态种子数据。(我正在删除、重新创建、迁移和重新植入测试数据库,并在单元测试运行之前确认数据在那里。)

    结果是这个断言在seeds.rb中成功,但在一行测试中失败:

    assert_equal 51, State.all.size
    
    1) Failure:
    test_state_seeds_are_present(StateTest) [/test/unit/state_test.rb:24]:
    <51> expected but was
    <0>.
    1 tests, 1 assertions, 1 failures, 0 errors
    

    我尝试了在基本测试类fixtures语句中显式列出非状态模型,以及翻转事务性fixtures标志(如预期,这只影响在测试期间创建的记录)。当然,正在考虑的测试本身并不是删除这些记录。

    状态记录总是被删除。有没有一种方法可以让Rails直接从种子数据中脱离出来?是否需要复制设备中的所有数据以确保重新加载?除了重大政治事件,我预计国家数据将相对稳定。

    蒂亚

    6 回复  |  直到 6 年前
        1
  •  12
  •   Community c0D3l0g1c    7 年前

    测试从数据库中删除所有数据,然后加载设备(如果有)。

    您需要让测试助手在测试运行之前加载种子文件。有几种方法可以做到这一点,请看我的类似问题: How to load db:seed data into test database automatically?

    最简单的方法可能只是添加

    require "#{Rails.root}/db/seeds.rb"

    到您的test_helper.rb文件的顶部(假设您使用内置的测试框架)。

        2
  •  4
  •   Steve Weet    15 年前

    “种子”特性没有集成到测试体系结构中。测试是围绕设备构建的,每次运行测试套件时,Rails都从设备加载数据并替换现有内容。

    但是,使用种子数据填充数据库非常简单。

    在测试helper.rb文件中,在基础中添加新的安装方法 ActionSupport::TestCase 班级。

    class ActionSupport::TestCase < ...
    
      setup :load_seeds
    
      protected 
    
        def load_seeds
          load "#{Rails.root}/db/seeds.rb"
        end
    
    end
    
        3
  •  0
  •   Steve Weet    15 年前

    我同意WEPPOS的最佳方法,但是为了完整性,为了可能已经拥有设备文件的人,您可以采用其他方法,并从现有设备中创建数据库。

    这是通过在db/seeds.rb文件中执行如下操作来实现的

    RAILS_FIXTURES = "#{Rails.root}/spec/fixtures"
    
    models_loaded_from_fixtures = %w[Modela Modelb Modelc ....]
    
    models_loaded_from_fixtures.each do |model|
      Fixtures.create_fixtures(RAILS_FIXTURES, "#{model.tableize}")
      puts "Loaded #{model.constantize.all.size} #{model.pluralize}"
    end
    

    您也可以读取fixes目录并创建一个要处理的文件名数组,我选择了上面的过程,因为我希望能够指定我希望为db种子植入的现有fixes中的哪一个。

        4
  •  0
  •   Patrick Reagan    15 年前

    我首先质疑是否需要编写这样的测试。您是在测试Seed数据rake任务是否正常工作,还是要测试状态类实现的行为?我假设是后者,所以我将编写关注行为的测试,并使用工厂女孩(或类似的),因为您提到您没有使用设备。确保移除 fixtures :all 线从 test/test_helper.rb .

    要将任务注入到正常的运行测试流中,这是一种始终适用于我的方法:

    namespace :test do
      task :force_environment do
        ENV['RAILS_ENV'] = 'test'
        RAILS_ENV.replace('test')
      end
    end
    
    %w(test:units test:functionals test:integration).map do |task_name|
      task = Rake::Task[task_name]
      task.clear_prerequisites
    
      task.enhance %w(db:test:prepare test:force_environment db:seed)
    end
    

    把它放在一个叫做 lib/tasks/testing.rake 下次跑步时它会被捡起来的 rake test 或其他与测试相关的任务。

        5
  •  0
  •   Marlin Pierce    13 年前

    我也有同样的问题,但标准答案对我不起作用。

    我的问题涉及到类文件中的位置,这些文件对常量和命名为_scope的数据库进行了查找。我找不到任何方法在正确的时间加载种子数据。

    我确实找到了一种绕过删除的方法,即使我删除了缺失表的fixture文件,也会发生这种情况。

    rails_env=测试耙db:种子 ruby-itest测试/单位/*.rb

        6
  •  0
  •   pokka    6 年前

    你不能两者都适用 seed fixtures 设置相同 table 默认情况下的数据。

    如果你设置了一个名为 products.yml ,创建时将“从产品中删除数据” 夹具 .

    你可以:

    1. 移动 种子 的舞台 夹具 S(手动加载种子);
    2. 只使用其中一个,或者使用另一种方法来管理测试数据;
    3. 不要使用这两种方法来设置同一个表的数据;
    4. 在Rails4.2中,您可以破解 line 在你 test_helper.rb 这样地:

    >

    require 'rails/test_help'
    
    class ActiveRecord::FixtureSet
      def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
        ...
        # table_rows.each_key do |table|
        #   conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
        # end
        ...
      end
    

    这在一些遗留的案例中会有所帮助,但会造成混乱 seeds 夹具 上升可能带来新的问题。