- Added guidance for when random values are unavoidable, recommending
FactoryBotsequences and rewinding them before each example - Added a “If you must use Faker” section showing how to set a fixed random seed and clear
Faker::UniqueGeneratorbefore each test
Changes
-Tests are about 100% control over UI interaction and your test scenario. Randomness makes writing tests hard. You will also push tests that are green for you today, but red for a colleague tomorrow.- +Tests are about 100% control over UI interaction and your test scenario. Randomness will eventually cause flaky tests that are hard to debug.
-That said, please don't do something like this:- +
- +The case against random values
- +------------------------------
- +
- +Avoid setting attributes to random values like this:
- +
- +```ruby
- +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:
- ```ruby
-Factory(:document) do |document|-document.category { ['foo', 'bar', 'baz'].sample }- +factory(:document) do |document|
- + category 'foo'
- end
- ```
-Instead do this:-- +### If you must use random values
- +
- +If you absolutely cannot use the same attribute value for every record, use a [FactoryBot sequence](https://thoughtbot.github.io/factory_bot/ref/sequence.html) and reset if before every example:
- +
- +```ruby
- +factory(:document) do |document|
- + sequence(:category) { |i| ['foo', 'bar', 'baz'][i % 3] }
- +end
- +```
- +
- ```ruby
-Factory(:document) do |document|-document.category 'foo'- +# 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](https://github.com/faker-ruby/faker). 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:- +I even recommend to **not** use libraries like [Faker](https://github.com/faker-ruby/faker). 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:
- ```ruby
- 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.- +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:
- +
- +```ruby
- +# spec/support/faker.rb
- +
- +RSpec.configure do |config|
- + config.prepend_before do
- + Faker::Config.random = Random.new(42)
- + Faker::UniqueGenerator.clear
- + end
- +end
- +```
- +
Posted by Henning Koch to makandra dev (2026-08-11 08:39)