---
title: 'Getting Sequential: A look into a Factory Bot Anti-pattern'
teaser:
tags: web,open source,testing,rails,good code,factory_girl,factory_bot
author: Josh Clayton
published_on: 2011-10-03
---

I've noticed a handful of what I'd consider Factory Bot anti-patterns, either
through pull requests, GitHub issues, or questions spread across Stack
Overflow, Google Groups, etc. The more common they are, the more I realize
that it will benefit plenty of other developers down the road if a list of
anti-patterns can be identified and what to do instead.

The one I'd like to outline today is based off of a request to make Factory
Bot sequences reset after every test run. The idea of resetting sequences
after every run is that then you can start to program against these names in
step definitions. For example, imagine the factory:

    FactoryBot.define do
      factory :category do
        sequence(:name) {|n| "Category #{n}" }
      end

      # ... more factories
    end

And the scenario:

    Scenario: Create a post under a category
      Given a category exists
      And I am signed in as an admin
      When I go to create a new post
      And I select "Category 1" from "Categories"
      And I press "Create"
      And I go to view all posts
      Then I should see a post with the category "Category 1"

That first step is given to us by Factory Bot (check out the [Cucumber integration
on the factory_bot wiki](https://github.com/thoughtbot/factory_bot/wiki/Integration:-Cucumber)
to find out more) and will create a category without overriding any of the
defaults provided by that factory.

If all sequences were reset after every run, it'd be safe to assume that the
category created as the first step of the scenario will create a category
named "Category 1".

There are two problems with this approach. Firstly, we're now tightly coupling
the scenarios to naming conventions outlined in the factories. If the sequence
logic changes, all the scenarios that rely on that naming convention will
break. Not fun. Secondly, it's not at all obvious where that "Category 1"
record was created. If I'm a developer who's looking at this code with a fresh
set of eyes, I'd assume that this category was created from a global setup or
seed file instead of being assigned in the first step of the scenario.

The solution is to name the category explicitly.

    Scenario: Create a post under a category
      Given a category exists with a name of "Category 1"
      And I am signed in as an admin
      When I go to create a new post
      And I select "Category 1" from "Categories"
      And I press "Create"
      And I go to view all posts
      Then I should see a post with the category "Category 1"

The first step is, again, given by Factory Bot and allows us to set the name
attribute.  It's now immediately obvious that the category we're creating is
the one we're using throughout the scenario, we're not reliant on a naming
convention outlined by Factory Bot, and any other developer looking at the
code won't question where this category was created.

Factory Bot's sequences are a great way to ensure that models with uniqueness
don't run into any naming collisions, and it's handy to have recognizable data
(instead of having every bit of data in tests runs be virtually the same).
That said, when writing tests against data where the values matter, don't
leave those values to chance; assign them outright. Give them *weight*. The
intent is much more obvious, less error prone, and requires no patches to
Factory Bot.

* * *

**Disclaimer:**

Looking for FactoryGirl? The library was renamed in 2017.
[Project name history can be found here.](https://github.com/thoughtbot/factory_bot/blob/master/NAME.md)
