Rails,成为朋友并在测试套件

时间:2015-05-26 22:53:06

标签: ruby-on-rails ruby-on-rails-3

工作正在从Rails 3过渡到Rails 4.在开发方面,一切似乎都或多或少地顺利运行,但是当所有套件(单元,功能和集成)运行时,测试会导致多种不同的故障一个人去rake:test

有趣的是,单独运行每个套件都不会产生任何故障。这强烈暗示数据库不会像在Rails 3中那样重置我们在Rails 4中的测试。

我已经尝试覆盖rake:test任务以在运行每个套件之前执行db:test:prepare,但这显然不符合我的想法,或者更确切地说,我希望它做什么,哪个是为每个测试使用一组新的数据,因此独立于其他所有测试成功或失败 - 在我们的Rails 3设置中它(已经或应该是)的方式。

为什么会这样?我该如何解决?

(请注意,测试框架是带有夹具等的vanilla Rails。我们得到的测试失败通常是外键错误或数据以预期方式更改的失败,当DB重置时不会显示在测试套件之前。)

编辑:

以下是我对Rakefile所做的更改。我们的想法是获得rake:test,就像在Rails 3中一样,除了在单元,功能和集成套件之间正确地重置数据库之外。

# /Rakefile

task :test => [];
Rake::Task[:test].clear
task :test do
    puts Rails.env
    if Rails.env == "test"
        puts "units"
        # Rake::Task["db:drop"].execute - results in 'test database not configured' error
        # Rake::Task["db:reset"].execute - results in 'relation 'table' does not exist' error
        Rake::Task["db:create"].execute
        Rake::Task["db:migrate"].execute
        Rake::Task["test:units"].execute
        puts "functionals"
        Rake::Task["db:schema:load"].execute
        Rake::Task["test:functionals"].execute
        puts "integration"
        Rake::Task["db:schema:load"].execute
        Rake::Task["test:integration"].execute
    end
end

编辑2:

Rails版本4.1.8

这是我的test_helper。我省略了不能使用我们数据的辅助方法,因为我可能不允许共享它们,而且它们与测试数据库的加载方式无关。

另请注意,我们还有一个自定义schema.rb,从中生成测试数据,因为尝试从迁移创建它们不支持我们在最终产品中需要的一些自定义功能/行为,例如物化观点。编辑后的内容将包含在<>>。

#test_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
include ActionDispatch::TestProcess

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
  #
  # Note: You'll currently still have to declare fixtures explicitly in integration tests
  # -- they do not yet inherit this setting
  set_fixture_class <<cached_object>>: ResultsDb::<<DesiredObjectClass>>Cache
  fixtures :all

  # Add more helper methods to be used by all tests here...
  def reload_contig(contig_sym)
    contig = contigs(contig_sym)

    src = contig.src
    new_tig = Contig.new(
              org: contig.org,
              version: contig.version,
              size: contig.size,
              sha1: contig.sha1,
              active: contig.active,
              src_id: src.id,
              src_type: contig.src_type)

    new_tig.id = contig.id
    contig.destroy
    unless new_tig.save
      raise new_tig.errors.full_messages.inspect
    end
    src.contigs << new_tig
    src.save
    new_tig
  end

  def reload_coord(coord_sym)
      coord = coords(coord_sym)

      new_coord = Coord.new(
          :mapped_id => coord.mapped_id,
          :mapped_type => coord.mapped_type,
          :contig_id => coord.contig_id,
          :contig_type => coord.contig_type,
          :start => coord.start,
          :stop => coord.stop,
          :fwd_strand => coord.fwd_strand
      )
      new_coord.id = coord.id
      coord.destroy
      new_coord.save!
  end
end

3 个答案:

答案 0 :(得分:2)

您可以查看专门用于帮助您在Rails测试期间保持数据库一致性和清洁度的DatabaseCleaner gem。

当我的代码绕过ActiveRecord并直接操作数据时,我才会遇到问题。在所有其他情况下,这个宝石对我来说非常适合测试。

答案 1 :(得分:2)

假设您目前使用的是Rails 4.0,那么当前的方法是您无法添加database_cleaner gem时可以做的最好的方法。 (我建议你总是喜欢db:schema:loaddb:migrate - 没有理由在测试环境中从一开始就完成所有的迁移,除非你做了一些不寻常的事情。)但是一旦你进入Rails 4.1或更高版本,你就有了更好的解决方案。

从Rails 4.1开始,management of the test database schema was automatedrake db:test:prepare已弃用。如果此时重新生成test_helper.rb,一切都应该神奇地起作用。

答案 2 :(得分:0)

您是否尝试在覆盖rake:test

时添加其中任何一项
rake db:reset db:migrate

rake db:drop db:create db:migrate

这个问题与this one类似。我知道我总是建立自己的rake db:recreate来为测试数据做这种事情。