Claude Code Factory Bot Test Data Guide
Factory Bot is a Ruby library for building test data fixtures in a flexible and maintainable way. When combined with Claude Code, you can automate factory creation, generate complex test scenarios, and build robust test suites faster than ever.
Understanding Factory Bot Basics
Factory Bot replaces traditional Rails fixtures with a more expressive, configurable approach to test data. Instead of static YAML files, you define factories as Ruby classes that can generate objects with default values, associations, and dynamic attributes.
Setting Up Factory Bot in Your Project
First, add Factory Bot to your Gemfile:
group :test do
gem 'factory_bot_rails'
end
Then run bundle install and configure Factory Bot in your test setup:
# spec/rails_helper.rb
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
Defining Your First Factory
Create factories in spec/factories/ with a clear, consistent naming convention:
# spec/factories/users.rb
FactoryBot.define do
factory :user do
sequence(:email) { |n| "user#{n}@example.com" }
first_name { "John" }
last_name { "Doe" }
password { "securePassword123" }
admin { false }
factory :admin_user do
admin { true }
role { "admin" }
end
end
end
Using Factory Bot with Claude Code
When working with Claude Code, you can use its understanding of Factory Bot to generate factories for your existing models and create sophisticated test data scenarios.
Generating Factories from Models
Ask Claude Code to analyze your models and create appropriate factories:
Create Factory Bot factories for my User, Post, and Comment models.
Include associations, valid sequences, and trait variations for common states.
Claude Code will generate factories similar to:
# spec/factories/posts.rb
FactoryBot.define do
factory :post do
title { "Sample Post Title" }
body { "This is the post content body." }
published { false }
association :author, factory: :user
trait :published do
published { true }
published_at { Time.current }
end
trait :draft do
published { false }
end
factory :published_post, traits: [:published]
factory :draft_post, traits: [:draft]
end
end
# spec/factories/comments.rb
FactoryBot.define do
factory :comment do
body { "Great article!" }
association :post
association :author, factory: :user
end
end
Building Complex Test Scenarios
Factory Bot shines when you need to create related records for testing complex associations:
# Creating a post with multiple comments
let(:post_with_comments) do
create(:post, :published).tap do |post|
create_list(:comment, 3, post: post)
end
end
# Creating a user with posts
let(:prolific_author) do
create(:user, first_name: "Prolific").tap do |user|
create_list(:post, 10, :published, author: user)
end
end
Advanced Factory Bot Patterns
Using Transient Attributes
Transient attributes don’t map directly to model fields but customize factory behavior:
FactoryBot.define do
factory :order do
transient do
item_count { 3 }
include_discount { false }
end
after(:build) do |order, evaluator|
if evaluator.include_discount
order.discount_percentage = 15
end
end
after(:create) do |order, evaluator|
create_list(:line_item, evaluator.item_count, order: order)
end
end
end
Factory Sequences for Unique Data
Ensure unique values across test runs with sequences:
FactoryBot.define do
factory :account do
sequence(:subdomain) { |n| "company#{n}" }
sequence(:email) { |n| "admin#{n}@company.com" }
name { "Company Name" }
end
end
Inheritance and Aliases
Create base factories and extend them:
FactoryBot.define do
factory :post do
title { "Default Title" }
body { "Default body content" }
author
factory :article do
type { "Article" }
category { "tech" }
end
factory :announcement do
type { "Announcement" }
priority { "high" }
end
end
factory :guest_post, parent: :post do
author { create(:user, :guest) }
end
end
Integration with RSpec
Factory Bot Methods in Tests
After configuring the syntax methods, use factories directly in your tests:
RSpec.describe Post do
describe "#publish!" do
it "changes published status to true" do
post = create(:post, :draft)
post.publish!
expect(post.published?).to be true
end
it "sets published_at timestamp" do
post = create(:post, :draft)
expect { post.publish! }.to change(post, :published_at).from(nil)
end
it "notifies followers" do
post = create(:post)
follower = create(:user, :following, post: post)
expect { post.publish! }.to change { follower.notifications.count }.by(1)
end
end
end
Using Factory Traits for Test Variations
Organize test data variations with traits:
RSpec.describe User do
describe "#can_post?" do
context "with active subscription" do
let(:user) { create(:user, :active, subscription: "pro") }
it { expect(user.can_post?).to be true }
end
context "with basic subscription" do
let(:user) { create(:user, :active, subscription: "basic") }
it { expect(user.can_post?).to be false }
end
context "with inactive account" do
let(:user) { create(:user, :inactive) }
it { expect(user.can_post?).to be false }
end
end
end
# Factory with traits
FactoryBot.define do
factory :user do
name { "Test User" }
subscription { "free" }
trait :active do
active { true }
end
trait :inactive do
active { false }
end
end
end
Best Practices for Factory Bot
Keep Factories Fast
Avoid slow operations in factories:
# Bad - file processing in factory
factory :document do
file { File.open(Rails.root.join("spec/fixtures/large.pdf")) }
end
# Good - minimal, fast factory
factory :document do
filename { "document.pdf" }
content_type { "application/pdf" }
end
Use build_stubbed for Unit Tests
For tests that don’t hit the database, use stubbed objects:
# Much faster - no database write
user = build_stubbed(:user)
expect(user.name).to eq("John Doe")
Clean Up Between Tests
Factory Bot handles cleanup automatically, but for performance-critical tests:
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
FactoryBot.lint
end
end
Working with Associations
Handling Dependent Records
FactoryBot.define do
factory :project do
name { "My Project" }
owner
# Automatically create owner if not provided
association :owner, factory: :user
# With nested attributes
factory :project_with_tasks do
after(:create) do |project|
create_list(:task, 5, project: project)
end
end
end
end
Self-Referential Associations
FactoryBot.define do
factory :user do
sequence(:username) { |n| "user#{n}" }
factory :user_with_friends do
after(:create) do |user|
friend1 = create(:user)
friend2 = create(:user)
user.friendships.create!(friend: friend1)
user.friendships.create!(friend: friend2)
end
end
end
end
Conclusion
Factory Bot combined with Claude Code creates a powerful testing workflow. Use Claude Code to generate factories from your models, create test data scenarios, and maintain clean, reusable factory definitions. This approach ensures your test suite remains fast, maintainable, and expressive.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one