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
3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Head First Fixture Replacement
ペパボ社内の RSpec 勉強会で Fixture Replacement について発表したスライドです。
Kensuke Nagae
March 21, 2012
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
190
Grape による API 実装 in action
kyanny
7
7.3k
<%= link_to "bundle", "update" %> - Make "bundle update" more fun to review
kyanny
2
5.4k
Web Developer Seminar
kyanny
0
2k
Heroku を利用した Quipper の開発事例紹介
kyanny
11
3.4k
Continuous gem dependency updating with Jenkins and Pull Request
kyanny
9
3.5k
Other Decks in Programming
See All in Programming
リアルな遅延を測る仕様
kota_yata
1
120
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
230
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
280
【デモ】Kiroで体験する仕様駆動開発|設計からコーディングまでAIと進める開発フロー
cmkudo
0
280
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
140
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
220
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
340
Oxlintはいいぞ(続)
yug1224
1
270
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
530
FastAPI の並行処理モデルを完全に理解する
hoto17296
1
730
不幸な GC
chencmd
0
300
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
120
Featured
See All Featured
How GitHub (no longer) Works
holman
316
150k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
390
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Product Roadmaps are Hard
iamctodd
55
12k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Site-Speed That Sticks
csswizardry
13
1.5k
Thoughts on Productivity
jonyablonski
76
5.3k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Mobile First: as difficult as doing things right
swwweet
225
10k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
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