Ruby: Don't build randomness into your factories

Updated . Posted . Visible to the public. Repeats.

Tests are about 100% control over UI interaction and your test scenario. Randomness will eventually cause flaky tests that are hard to debug.

The case against random values

Avoid setting attributes to random values like this:

factory(:document) do |document|
  category { ['foo', 'bar', 'baz'].sample }
end

This makes tests randomly fail when they expect "foo" for some other reason, but an unreleated document in the "foo" category happens to also be on the screen.

Instead just use the same attribute value every time:

factory(:document) do |document|
  category 'foo'
end

If you must use random values

If you absolutely cannot use the same attribute value for every record, use a FactoryBot sequence Show archive.org snapshot and reset if before every example:

factory(:document) do |document|
  sequence(:category) { |i| ['foo', 'bar', 'baz'][i % 3] }
end
# spec/support/factory_bot.rb

RSpec.configure do |config|
  config.prepend_before do
    FactoryBot.rewind_sequences
  end
end

The case against Faker

I even recommend to not use libraries like Faker Show archive.org snapshot . Faker makes awesome sample data, but at the risk of adding random strings to your screen.

When your factory requires unique values for something, prefer numbering fixed strings intead:

FactoryBot.define do
  sequence(:first_name)   { |i| "First#{i}" }
  sequence(:last_name)    { |i| "Last#{i}" }
  sequence(:company_name) { |i| "Company #{i}" }
end

This creates ugly sample data like "First3 Last3", but e.g. doesn't make tests pass when they shouldn't.

If you must use Faker

If you must use Faker (e.g. you inherited a large test suite), at least use the same random seed for every test:

# spec/support/faker.rb

RSpec.configure do |config|
  config.prepend_before do
    Faker::Config.random = Random.new(42)
    Faker::UniqueGenerator.clear
  end
end
Profile picture of Henning Koch
Henning Koch
Last edit
Henning Koch
Keywords
blueprints, factory_girl, machinist, flaky
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2014-02-24 11:31)