Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Head First Fixture Replacement
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kensuke Nagae
March 21, 2012
Programming
1
2.9k
Head First Fixture Replacement
ペパボ社内の RSpec 勉強会で Fixture Replacement について発表したスライドです。
Kensuke Nagae
March 21, 2012
Tweet
Share
More Decks by Kensuke Nagae
See All by Kensuke Nagae
スタディサプリ開発チームのこれまでとこれから / StudySapuri Product Meetup #1
kyanny
0
2.6k
Tokyo Web Dev hiring discussion session
kyanny
0
13k
sbpayment.rbのご紹介
kyanny
0
2.2k
#AsiaDevNight
kyanny
0
170
Grape による API 実装 in action
kyanny
7
7.2k
<%= link_to "bundle", "update" %> - Make "bundle update" more fun to review
kyanny
2
5.3k
Web Developer Seminar
kyanny
0
1.9k
Heroku を利用した Quipper の開発事例紹介
kyanny
11
3.4k
Continuous gem dependency updating with Jenkins and Pull Request
kyanny
9
3.4k
Other Decks in Programming
See All in Programming
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
690
Strategy for Finding a Problem for OSS: With Real Examples
kibitan
0
110
今からFlash開発できるわけないじゃん、ムリムリ! (※ムリじゃなかった!?)
arkw
0
160
AIコードレビューの導入・運用と AI駆動開発における「AI4QA」の取り組みについて
hagevvashi
0
560
Linux Kernelの1文字のミスで 権限昇格ができた話
rqda
0
2.2k
Ruby and LLM Ecosystem 2nd
koic
1
1.3k
OTP を自動で入力する裏技
megabitsenmzq
0
130
LM Linkで(非力な!)ノートPCでローカルLLM
seosoft
0
240
CSC307 Lecture 15
javiergs
PRO
0
270
我々はなぜ「層」を分けるのか〜「関心の分離」と「抽象化」で手に入れる変更に強いシンプルな設計〜 #phperkaigi / PHPerKaigi 2026
shogogg
2
610
「接続」—パフォーマンスチューニングの最後の一手 〜点と点を結ぶ、その一瞬のために〜
kentaroutakeda
4
2k
どんと来い、データベース信頼性エンジニアリング / Introduction to DBRE
nnaka2992
1
340
Featured
See All Featured
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Writing Fast Ruby
sferik
630
63k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
480
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
410
Marketing to machines
jonoalderson
1
5.1k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
700
What's in a price? How to price your products and services
michaelherold
247
13k
KATA
mclloyd
PRO
35
15k
Rails Girls Zürich Keynote
gr2m
96
14k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.7k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
110
Practical Orchestrator
shlominoach
191
11k
Transcript
Head First Fixture Replacement @kyanny
Disclaimer: Samples Are Not Smartest, Not Enough, Not Exactly Correct
Test Environment then Fixture then Fixture Replacement
Test Environment
Test Suite Requires Isolate Environment
Unified Environment
User.create assert User.count == 1 # SUCCESS
User.create # Oops! Someone Create User # POST /users/create assert
User.count == 1 # FAIL
Isolate Environment
mysql> show databases; +--------------------+ | Database | +--------------------+ | development
| | test | | production | +--------------------+
User.create # For Development Environment # POST /users/create assert User.count
== 1 # SUCCESS
Fixture
Fixture == Dummy Data for Tests
: ( user = User.create user.albums << Album.create user.albums <<
Album.create user.albums << Album.create assert user.albums.count >= 3
# fixtures/users.yml alice: id: 1 email:
[email protected]
bob: id: 2
email:
[email protected]
# fixtures/albums.yml one: user_id: 1 two: user_id: 1 three: user_id:
1
: ) fixtures :users fixtures :albums user = users(:alice) assert
user.albums.count >= 3
But... DRY
Fixture is Too Difficult To Maintain
Complex Association
# User has_many :bookmarks has_many :pages, :through => :bookmarks #
Page has_many :bookmarks has_many :users, :through => :bookmarks # Bookmark belongs_to :user belongs_to: page
# fixtures/users.yml alice: id: 1 email:
[email protected]
bob: id: 2
email:
[email protected]
# fixtures/pages.yml twitter: id: 1 url: http://twitter.com/ facebook: id: 2
url: http://facebook.com/
# fixtures/bookmarks.yml alice_twitter: user_id: 1 page_id: 1 bob_facebook: user_id: 2
page_id: 1 # Oops! Wrong id
bob = users(:bob) assert bob.pages.first.url == "http://facebook.com/" # FAIL
Complex Data
# fixtures/photos.yml one: album_id: 1 exif: | --- width: 1024
height: 768 f_number: 280/100
Fixture is Too Difficult To Maintain
Fixture Replacement
Fixture Replacement == Skeleton of Dummy Data for Tests
Fixture == Data itself Fixture Replacement == Skeleton of Data
# factories/users.rb Factory.define(:album) do |a| a.title "Album Title" a.password "Album
Password" end album = Factory.create(:album) album = Factory.create(:album, :title => "Happy Wedding")
# factories/users.rb Factory.define(:alice) do |u| u.email "
[email protected]
" end Factory.define(:bob) do
|u| u.email "
[email protected]
" end
# factories/users.rb Factory.sequence(:email) do |n| "user_#{n}@example.com" end Factory.define(:user) do |u|
u.email { Factory.next(:email) } end
Flexible
# factories/pages.rb Factory.define(:twitter) do |p| p.url "http://twitter.com/" end Factory.define(:facebook) do
|p| p.url "http://facebook.com/" end
# factories/users.rb Factory.define(:alice) do |u| u.pages {[ Factory(:twitter) ]} end
Factory.define(:bob) do |u| u.pages {[ Factory(:facebook) ]} end
bob = Factory.create(:bob) assert bob.pages.first.url == "http://facebook.com/" # SUCCESS
But... Flexible
Fixture Replacement is Not a Silver Bullet
Children w/ Independent Parent
# factories/albums.rb Factory.define(:album) do |a| a.user { Factory(:user) } end
Factory.define(:paid) do |a| a.user { Factory(:user) } end
3.times do album = Factory.create(:album) end paid = Factory.create(:paid) user
= paid.user assert user.albums.count == 4 # FAIL
user = Factory.create(:user) 3.times do Factory(:album, :user => user) end
Factory(:paid, :user => user) assert user.albums.count == 4 # SUCCESS
Not DRY
Proposal: Fixture w/ Fixture Replacement
Test Context Arrangement Recipebook
First, Use Fixture. Complex, Then Use Fixture Replacement.
# fixtures/users.yml alice: id: 1 bob: id: 2
# fixtures/albums.yml one: user_id: 1 two: user_id: 1 three: user_id:
1 four: user_id: 1
fixtures :all user = users(:alice) assert user.albums.count == 4 #
SUCCESS
# factories/photos.rb exif = { :width => 1024, :height =>
768 } Factory.define(:photo) do |p| p.exif { exif.to_yaml } end
photo = Factory.create(:photo) assert photo.exif[:width] == 1024 # SUCCESS
Use The Right Tool In The Right Place
http://www.func09. com/wordpress/archives/532 http://eblog.drecom.jp/entry/14 http://www.slideshare.net/moro/test- context-arrangement-recipebook http://d.hatena.ne. jp/a666666/20110220/1298135559
end
Kensuke Nagae blog.kyanny.me @kyanny