Share
Embed
FactoryBotアンチパターン / factory_bot anti-patterns
[Kaigi on Rails 2026 過去登壇勉強会 - connpass](https://connpass.com/event/406332/) での発表資料です。
toshimaru
October 05, 2026
Transcript
38 slides
-
自己紹介 toshimaru 2025年6月〜 SmartBank Inc. 推しモデル: GPT-6 Astra Opus5.5 FactoryBot
アンチパターン 2 Kaigi on Rails 2026 過去登壇勉強会 -
Rails World 2026 アンチパターン RailsFactoryBot World 2026 Opening Keynote -
DHH Kaigi on Rails 2026 過去登壇勉強会 -
発表当時の状況 • コロナ禍のため、ビデオ登壇 • 「rspec の正しい書き方」 みたいな話は巷にあった • FactoryBot に特化した話は巷に見かけなかった
• rubocop-factory_bot 未リリース • 2023年5月: rubocop-factory_bot リリース • 正確に言うと、rubocop-rspec に RSpec/FactoryBot/* が内包されていたが、そ こまでルールが多くなく、あまり活用されていなかった FactoryBot アンチパターン 9 Kaigi on Rails 2026 過去登壇勉強会 -
発表の経緯 FactoryBot のコードが荒れ気味だった factory_bot/GETTING_STARTED.md を読んだら、意外と知らないことや有益な 情報が多かった。 FactoryBot の正しい書き方の発信 FactoryBotの正しい書き方・マナー(The Right
Way / The Good Way)を発表 することは価値があると思った。 FactoryBot アンチパターン 10 Kaigi on Rails 2026 過去登壇勉強会 -
紹介するアンチパターン 01 巨大デフォルトデータ 05 独自 sequence id 02 無駄 create
06 同じ値のテスト 03 Too Many Traits 07 無駄 list 生成 04 DRY じゃない Traits 08 Always Create Association ※ それぞれのアンチパターンの詳細については、オリジナル資料を参照 FactoryBot アンチパターン 15 Kaigi on Rails 2026 過去登壇勉強会 -
前提 class User < ApplicationRecord has_many :posts end class Post
< ApplicationRecord belongs_to :user end FactoryBot アンチパターン 17 Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :user do sequence(:id) name { "User
Name" } after(:create) do |user| create_list(:post, 10, user: user) end end end FactoryBot アンチパターン 18 Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :user do sequence(:id) name { "User
Name" } after(:create) do |user| create_list(:post, 10, user: user) end end end FactoryBot アンチパターン 19 独自 sequence id 同じ値のテスト 巨大デフォルトデータ 無駄 list 生成 Kaigi on Rails 2026 過去登壇勉強会 -
Good FactoryBot.define do factory :user do sequence(:name) { |n| "User
Name#{n}" } # Faker::Name.name でも OK trait :with_posts do transient do posts_count { 3 } end after(:create) do |user, evaluator| create_list(:post, evaluator.posts_count, user: user) end end end end FactoryBot アンチパターン 20 Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :user do role { :general }
trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end trait :deleted_admin do role { :admin } deleted_at { Time.current } end end end # 呼び出し側 FactoryBot.create(:user, :deleted_admin) FactoryBot アンチパターン 22 Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :user do role { :general }
trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end trait :deleted_admin do role { :admin } deleted_at { Time.current } end end end DRY でない traits • • :admin と重複 :deleted と重複 # 呼び出し側 FactoryBot.create(:user, :deleted_admin) FactoryBot アンチパターン 23 Kaigi on Rails 2026 過去登壇勉強会 -
Good FactoryBot.define do factory :user do role { :general }
trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end end end # 呼び出し側 FactoryBot.create(:user, :admin, :deleted) FactoryBot アンチパターン 24 Kaigi on Rails 2026 過去登壇勉強会 -
POINT 2 trait は DRY に定義し、 「重ねて」使う。 FactoryBot アンチパターン 25
Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :post do sequence(:title) { |n| "Post
Title #{n}" } user { create(:user) } trait :title_blank do title { '' } end trait :title_too_long do title { 'a' * 1000 } end end end FactoryBot アンチパターン 26 Kaigi on Rails 2026 過去登壇勉強会 -
Bad FactoryBot.define do factory :post do sequence(:title) { |n| "Post
Title #{n}" } user { create(:user) } trait :title_blank do title { '' } end Too Many Traits 例外値 trait trait :title_too_long do title { 'a' * 1000 } end end end FactoryBot アンチパターン Always Create Association Too Many Traits 例外値 trait 27 Kaigi on Rails 2026 過去登壇勉強会 -
Good FactoryBot.define do factory :post do sequence(:title) { |n| "Post
Title #{n}" } user { association :user } # 単に user だけも可 end end FactoryBot アンチパターン 28 Kaigi on Rails 2026 過去登壇勉強会 -
POINT 3 例外値はテスト側で定義。 belongs̲to 関連は association で定義。 FactoryBot アンチパターン 29
Kaigi on Rails 2026 過去登壇勉強会 -
Bad RSpec.describe Post do describe "validations" do it "title が空なら
invalid" do post = create(:post) post.title = "" expect(post).to be_invalid end end end FactoryBot アンチパターン 30 Kaigi on Rails 2026 過去登壇勉強会 -
Bad RSpec.describe Post do describe "validations" do it "title が空なら
invalid" do post = create(:post) post.title = "" expect(post).to be_invalid end end end FactoryBot アンチパターン 31 無駄 create Kaigi on Rails 2026 過去登壇勉強会 -
Good RSpec.describe Post do describe "validations" do it "title が空なら
invalid" do post = build(:post, title: '') expect(post).to be_invalid end end end FactoryBot アンチパターン 32 Kaigi on Rails 2026 過去登壇勉強会 -
POINT 4 永続化が不要なら build を使う。 FactoryBot アンチパターン 33 Kaigi on
Rails 2026 過去登壇勉強会 -
Other Tips FactoryBot.lint Rails Enum Traits 登録されている Factory を実際に一 Active
Record モデルで定義された 通り生成してみて、バリデーション エラーや例外が発生しないかを チェック enum の各値に対応する trait を自動 FactoryBot アンチパターン 的に定義してくれる 34 Kaigi on Rails 2026 過去登壇勉強会