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
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.4k
Tokyo Web Dev hiring discussion session
kyanny
0
13k
sbpayment.rbのご紹介
kyanny
0
2k
#AsiaDevNight
kyanny
0
140
Grape による API 実装 in action
kyanny
7
7k
<%= link_to "bundle", "update" %> - Make "bundle update" more fun to review
kyanny
2
5k
Web Developer Seminar
kyanny
0
1.8k
Heroku を利用した Quipper の開発事例紹介
kyanny
11
3.3k
Continuous gem dependency updating with Jenkins and Pull Request
kyanny
9
3.2k
Other Decks in Programming
See All in Programming
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
4
960
生成AIコーディングとの向き合い方、AIと共創するという考え方 / How to deal with generative AI coding and the concept of co-creating with AI
seike460
PRO
1
330
VS Code Update for GitHub Copilot
74th
1
410
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
1
690
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
240
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
510
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
100
Team operations that are not burdened by SRE
kazatohiei
1
240
GraphRAGの仕組みまるわかり
tosuri13
8
490
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
47
31k
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
1.5k
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
390
Featured
See All Featured
Practical Orchestrator
shlominoach
188
11k
Thoughts on Productivity
jonyablonski
69
4.7k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
181
53k
How GitHub (no longer) Works
holman
314
140k
The Invisible Side of Design
smashingmag
300
51k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Gamification - CAS2011
davidbonilla
81
5.3k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Speed Design
sergeychernyshev
32
1k
Six Lessons from altMBA
skipperchong
28
3.8k
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