我发现了一篇关于Testing Factories First的博客文章(由BigBinary发布 - 恰好是Thoughtbot's RSpec original的Minitest / spec版本)。
你可以告诉我没有spec
框架的等价物 - 只需要Minitest(Rails)吗?
投机/ 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
Rake文件
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
投机/ 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 /任务/ 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
)?
我在下面介绍的方法与两个原始解决方案略有不同 - 从某种意义上说,我的方法只创建了一个测试,在这个测试中,我循环遍历工厂并对每个测试运行一个断言。我无法创建最接近原始解决方案的解决方案 - 这是(我相信)每个工厂的单独测试方法。如果有人能够展示这样的实现,那就太酷了。
测试/ 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 /任务/ 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(例如staging
或production
)将导致uninitialized constant MiniTest
。
当然我也可以直接运行工厂测试:
bundle exec ruby -I test test/aaa_factories_tests/factories_test.rb
这是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 /任务/ 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而不是任务测试。