【问题标题】:How to Test Factories First with Minitest but without the spec framework?如何在没有规范框架的情况下首先使用 Minitest 测试工厂?
【发布时间】:2013-11-14 18:41:00
【问题描述】:

我发现了一篇关于 Testing Factories First 的博文(BigBinary 撰写 - 恰好是 Thoughtbot's RSpec original 的 Minitest/spec 版本)。

能否请您给我看一下没有 spec 框架的等效项 - 仅使用 Minitest (Rails)?

Thoughtbot 方法 (RSpec)

spec/factories_spec.rb

FactoryGirl.factories.map(&:name).each do |factory_name|
  describe "The #{factory_name} factory" do
     it 'is valid' do
      build(factory_name).should be_valid
     end
  end
end

Rakefile

if defined?(RSpec)
  desc 'Run factory specs.'
  RSpec::Core::RakeTask.new(:factory_specs) do |t|
    t.pattern = './spec/factories_spec.rb'
  end
end

task spec: :factory_specs

BigBinary 方法(Minitest,规范)

spec/factories_spec.rb

require File.expand_path(File.dirname(__FILE__) + '/spec_helper')

describe FactoryGirl do
  EXCEPTIONS = %w(base_address base_batch bad_shipping_address)
  FactoryGirl.factories.each do |factory|
    next if EXCEPTIONS.include?(factory.name.to_s)
    describe "The #{factory.name} factory" do

      it 'is valid' do
        instance = build(factory.name)
        instance.must_be :valid?
      end
    end
  end
end

lib/tasks/factory.rake

desc 'Run factory specs.'
Rake::TestTask.new(:factory_specs) do |t|
  t.pattern = './spec/factories_spec.rb'
end

task test: :factory_specs

什么是 Minitest 等效项(没有 spec)?

【问题讨论】:

    标签: ruby-on-rails testing factory-bot minitest


    【解决方案1】:

    我在下面介绍的方法与两个原始解决方案略有不同 - 从某种意义上说,我的方法只创建一个测试,在其中我循环遍历工厂并对每个工厂运行一个断言。我无法创建一个更接近于模仿原始解决方案的解决方案 - 这是(我相信)每个工厂的单独测试方法。如果有人可以展示这样的实现,那就太酷了。

    test/aaa_factories_tests/factories_test.rb

    require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
    
    class FactoriesTest < Minitest::Unit::TestCase
    
      puts "\n*** Factories Test ***\n\n"
    
      EXCEPTIONS = %w(name_of_a_factory_to_skip another_one_to_skip)
    
      def test_factories
    
        FactoryGirl.factories.each do |factory|
    
          next if EXCEPTIONS.include?(factory.name.to_s)
    
          instance = FactoryGirl.build(factory.name)
          assert instance.valid?, "invalid factory: #{factory.name}, error messages: #{instance.errors.messages.inspect}"
    
          instance = factory = nil
        end         
      end   
    end
    

    感谢Minitest works out of the box 的方式 -- test/minitest-rails 下添加任何目录将自动为其创建关联的rake 任务。因此,假设您添加了一个test/api/ 目录,rake minitest:api 将自动可用。 -- 当我在没有其他配置的情况下运行bundle exec rake -T 时,我看到了任务:

    rake minitest:aaa_factories_tests    # Runs tests under test/aaa_factories_tests
    

    并且我能够成功运行此任务:

    -bash> bundle exec rake minitest:aaa_factories_tests
    
    *** Factories Test ***
    
    Run options: --seed 19208
    
    # Running tests:
    
    .
    
    Finished tests in 0.312244s, 3.2026 tests/s, 9.6079 assertions/s.
    
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
    

    尽管在目录前加上aaa 很丑陋,但我可以先用以下方法测试工厂:

    bundle exec rake minitest:all
    

    aaa prepend 解决方案的原因是 MiniTest does a Dir glob,而在 Mac OS X(和其他 Unix 变体)上,结果按字母顺序排序 (though the results differ across different platforms)。

    同样,我在the default_tasks array 前面加上aaa_factories_tests 以便在默认Minitest 任务 中首先测试工厂(即在运行bundle exec rake minitest 时)。

    lib/tasks/factories_first.rake

    MiniTest::Rails::Testing.default_tasks.unshift('aaa_factories_tests') if Rails.env =~ /^(development|test)\z/
    

    请注意,上述条件避免了在不可用的环境中错误地引用Minitest(我将minitest-rails 限制在:test:development 中的:development 组@ 中)。如果没有这个if-条件,推送到Heroku(例如stagingproduction)将导致uninitialized constant MiniTest

    当然我也可以直接运行工厂测试:

    bundle exec ruby -I test test/aaa_factories_tests/factories_test.rb
    

    【讨论】:

      【解决方案2】:

      这是一个没有规范框架的 MiniTest 解决方案:

      test/factories_test.rb

      require File.expand_path(File.dirname(__FILE__) + '/test_helper')
      
      class FactoriesTest < ActiveSupport::TestCase
        EXCEPTIONS = %w(griddler_email)
        FactoryBot.factories.map(&:name).each do |factory_name|
          next if factory_name.to_s.in?(EXCEPTIONS)
          context "The  #{factory_name} factory" do
            should 'be valid' do
              factory = build(factory_name)
              assert_equal true, factory.valid?, factory.errors.full_messages
            end
          end
        end
      end
      

      lib/tasks/factory.rake

      namespace :test do
        desc 'Test factories'
        Rake::TestTask.new(:factories) do |t|
          t.pattern = './test/factories_test.rb'
        end
      end
      
      task minitest: 'test:factories'
      

      如果您希望工厂测试在其他测试之前运行,最重要的是使用 taks minitest 而不是 task test

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-22
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 2016-12-04
        • 1970-01-01
        • 2015-07-12
        相关资源
        最近更新 更多