4

我发现了一篇关于首先测试工厂的博客文章(由 BigBinary 撰写——恰好是Thoughtbot 的 RSpec original的 Minitest/spec 版本)。

您能否向我展示没有spec框架的等价物 - 仅使用 Minitest(Rails)?

Thoughtbot 方法 (RSpec)

规格/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

耙文件

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,规范)

规格/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)?

4

2 回答 2

3

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

测试/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 开箱即用的方式——在下面添加任何目录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 前置解决方案的原因是MiniTestaDir glob和 on Mac OS X(以及其他 Unix 变体)结果按字母顺序排序(尽管结果在不同平台上有所不同)。

同样,我default_tasks数组前面加上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中的组Gemfile)。如果没有这个if- 条件,推送到 Heroku(例如 tostagingproduction)将导致uninitialized constant MiniTest.

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

bundle exec ruby -I test test/aaa_factories_tests/factories_test.rb
于 2013-11-29T02:05:55.990 回答
0

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

测试/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而不是任务测试。

于 2014-01-11T13:29:05.537 回答