我们应该在 Rails 工厂中使用 Faker 吗?

Should we be using Faker in Rails Factories?

我喜欢 Faker,我一直在 seeds.rb 中使用它来用看起来很真实的数据填充我的开发环境。

我也刚刚开始使用 Factory Girl,这也节省了很多时间 - 但是当我在网上搜索代码示例时,我没有看到太多将两者结合起来的证据。

问。人们不在工厂中使用 faker 有充分的理由吗?

我的感觉是,通过这样做,我可以通过每次播种随机但可预测的数据来提高测试的稳健性,这有望增加出现错误的机会。

但这也许是不正确的,与对工厂进行硬编码相比没有任何好处,或者我没有看到潜在的陷阱。这两个 gem 应该或不应该结合使用有充分的理由吗?

我喜欢使用 Faker,并且通常在处理较大的代码库时使用。当 Faker 和 Factory Girl 一起使用时,我看到了以下优点和缺点:

可能的缺点:

  • 重现完全相同的测试场景有点困难(至少 RSpec 通过每次显示随机数生成器种子来解决这个问题,并允许您使用它重现完全相同的测试)
  • 生成数据有点浪费性能

可能的优势:

  • 使显示的数据通常更易于理解。手动创建test-data时,人们倾向于各种short-cuts以避免繁琐。
  • 同时与Faker建立工厂进行测试,为您提供了生成漂亮演示数据的方法。
  • 当 运行 测试很多
  • 时,您可能会随机发现边缘案例错误

有些人反对,如here

DO NOT USE RANDOM ATTRIBUTE VALUES

One common pattern is to use a fake data library (like Faker or Forgery) to generate random values on the fly. This may seem attractive for names, email addresses or telephone numbers, but it serves no real purpose. Creating unique values is simple enough with sequences:

FactoryGirl.define do   
  sequence(:title) { |n| "Example title #{n}" }

  factory :post do
    title
  end 
end

FactoryGirl.create(:post).title # => 'Example title 1' 

Your randomised data might at some stage trigger unexpected results in your tests, making your factories frustrating to work with. Any value that might affect your test outcome in some way would have to be overridden, meaning:

Over time, you will discover new attributes that cause your test to fail sometimes. This is a frustrating process, since tests might fail only once in every ten or hundred runs – depending on how many attributes and possible values there are, and which combination triggers the bug. You will have to list every such random attribute in every test to override it, which is silly. So, you create non-random factories, thereby negating any benefit of the original randomness. One might argue, as Henrik Nyh does, that random values help you discover bugs. While possible, that obviously means you have a bigger problem: holes in your test suite. In the worst case scenario the bug still goes undetected; in the best case scenario you get a cryptic error message that disappears the next time you run the test, making it hard to debug. True, a cryptic error is better than no error, but randomised factories remain a poor substitute for proper unit tests, code review and TDD to prevent these problems.

Randomised factories are therefore not only not worth the effort, they even give you false confidence in your tests, which is worse than having no tests at all.

但是没有什么能阻止你去做,如果你想去做,就去做吧。

哦,在最近的 FactoryGirl 中有一种更简单的内联序列的方法,该引用是为旧版本编写的。

由你决定。

在我看来,在测试中使用随机数据是一个非常好的主意,它总是帮助我发现我没有想到的错误和极端情况。

我从不后悔拥有随机数据。 @jrochkind 描述的所有要点都是正确的(你应该在阅读这个之前阅读另一个答案)但是你也可以(并且应该)在你的 spec_helper.rb

中写下它
config.before(:all)  { Faker::Config.random = Random.new(config.seed) }

这将使您也可以使用可重复的数据进行可重复的测试。如果你不这样做,那么你就会遇到其他答案中描述的所有问题。