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
Test Your Legacy Code
Search
Noel Rappin
November 07, 2011
Technology
230
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Test Your Legacy Code
Presented at RubyMidwest, November 2011
Noel Rappin
November 07, 2011
More Decks by Noel Rappin
See All by Noel Rappin
Rails on Ruby: How Ruby Makes Rails Great
noelrap
0
420
In Defense of Metaprogramming
noelrap
0
560
Rails 7 Front End Tooling
noelrap
1
620
More Engineers, More Problems: Solutions for Big Teams
noelrap
0
240
The Rails 6 Front End: Building with Webpacker and Stimulus
noelrap
3
1.3k
The Developer's Toolkit
noelrap
0
250
High Cost Tests and High Value Tests: GOTO Chicago 2018
noelrap
2
180
High Cost Tests and High Value Tests
noelrap
1
220
The Road To Legacy is Paved With Good Intentions
noelrap
1
240
Other Decks in Technology
See All in Technology
AI工学特論: MLOps・継続的評価
asei
11
3k
セキュリティ研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
31
25k
AIQAのナレッジ構築について
qatonchan
1
130
StepFunctionsとGraphRAGを活用した暗黙知活用のためのRAG基盤
yakumo
0
190
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
7
1.8k
AIで楽になるはずが、なぜ疲れる?
kinopeee
0
140
CTOキーノート:AI時代の「つなぐ」を再定義 ― 真のIoTとリアルワールドAI【SORACOM Discovery 2026】
soracom
PRO
0
320
なぜ、あなたのエージェントは言うことを聞かないのか
segavvy
1
580
コンポーネント名には何を含めるべきなのか? / what-should-be-included-in-component-names
airrnot1106
0
180
『モンスターストライク』 の運営に伴走する! データ民主化への 解析グループの3つのアプローチ
mixi_engineers
PRO
0
180
検索技術知識0のエンジニアが広告検索システムを内製化して運用するまで
lycorptech_jp
PRO
0
160
現場をAIで動かす「フィジカル AI」の組み込み設計の考え方【SORACOM Discovery 2026】
soracom
PRO
0
150
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Fireside Chat
paigeccino
42
4k
Evolving SEO for Evolving Search Engines
ryanjones
0
250
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
230
Darren the Foodie - Storyboard
khoart
PRO
3
3.5k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
250
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
160
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
980
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
41k
Transcript
Test Your Legacy Code Noel Rappin @noelrap Monday, November 7,
11
You are handed a “rescue” project Monday, November 7, 11
Oh. My. God. The last person to work on this
was an idiot Monday, November 7, 11
Now what? Monday, November 7, 11
Shake your fists at the heavens for one minute. Photo
by Sha Sha Chu http://www.flickr.com/photos/shashachu/88654315/ Monday, November 7, 11
Get back to work. Monday, November 7, 11
What is a legacy application? Monday, November 7, 11
Code without tests Monday, November 7, 11
Code based on lost requirements Monday, November 7, 11
You don’t know what “correct” means Monday, November 7, 11
What’s your goal? Monday, November 7, 11
Respect working code. Do no harm. Monday, November 7, 11
Deliver features Monday, November 7, 11
At a sustainable pace Monday, November 7, 11
Improve code quality Monday, November 7, 11
The Boy Scout Rule Monday, November 7, 11
Our rescue project needs to change Monday, November 7, 11
Goofus and Gallant Monday, November 7, 11
“First, let’s write tests and cover the whole app” Monday,
November 7, 11
“That change is easy, I’ll just drop that in” Monday,
November 7, 11
They are both Goofus Monday, November 7, 11
Why not cover the whole app in tests? Monday, November
7, 11
“It’s a small world, but I wouldn’t want to paint
it” Monday, November 7, 11
It’s not a quick win Monday, November 7, 11
You can introduce bugs Monday, November 7, 11
Why not just drop something in? Monday, November 7, 11
It sets a bad precedent Monday, November 7, 11
It doesn’t make anything better Monday, November 7, 11
What’s a Gallant Software Craftsman to do? Monday, November 7,
11
The basic TDD process... Monday, November 7, 11
...applied to new changes only Monday, November 7, 11
Red. Green. Refactor. Monday, November 7, 11
Over time, coverage and quality grow organically Monday, November 7,
11
Okay, it’s not that easy Monday, November 7, 11
Why not? Monday, November 7, 11
You don’t know what to test Monday, November 7, 11
It’s hard to isolate objects under test Monday, November 7,
11
A friendly reminder: git is your friend Monday, November 7,
11
Cucumber Photo by karenandbradmerson http://www.flickr.com/photos/karenandbrademerson/492770419 Monday, November 7, 11
Cucumber is independent of the code Monday, November 7, 11
Cucumber can cover a lot of the app quickly Monday,
November 7, 11
But... Monday, November 7, 11
Cucumber is slow Photo by matley0 http://www.flickr.com/photos/matley0/2973398121/ Monday, November 7,
11
And it’s not great at isolating where a problem is
Monday, November 7, 11
Test-Driven Exploration Monday, November 7, 11
It’s like TDD... with cheating Monday, November 7, 11
Red. Make it green. Refactor. Monday, November 7, 11
The code is source of truth Monday, November 7, 11
Mock Testing Monday, November 7, 11
Mocks are fast and allow unit testing Monday, November 7,
11
But they can be hard to set up Monday, November
7, 11
Isolation Monday, November 7, 11
Only touch existing methods to call your new methods Monday,
November 7, 11
def crazy_insane_method return clean_new_method if new_condition # all the old
ugly stuff end Monday, November 7, 11
Seams Photo by boogah http://www.flickr.com/photos/boogah/4541496/ Monday, November 7, 11
Default method arguments Monday, November 7, 11
def crazy_insane_method(arg, arg, new_arg = nil) # crazy insane stuff
# now with new stuff end Monday, November 7, 11
Changing behavior without touching code Monday, November 7, 11
Monday, November 7, 11
class TestPurchase < Purchase def bang # no-op end end
user.purchase << TestPurchase.new Monday, November 7, 11
class Purchase def bang # no-op end end Monday, November
7, 11
Singleton classes Monday, November 7, 11
x = Purchase.new x.def bang # no-op end Monday, November
7, 11
Duck Typing Photo by Andyofne http://www.flickr.com/photos/andyofne/3757051334/ Monday, November 7, 11
class TestPurchase def bang # no-op end end user.purchase <<
TestPurchase.new Monday, November 7, 11
Use a pebble Photo by Slideshow Bruce http://www.flickr.com/photos/springfieldhomer/39079430/ Monday, November
7, 11
class Pebble def initialize(name) @name = name end def method_missing(method_name,
*args) p "#{method_name}(#{args.join(", ")}) from #{caller_method}" self end end Monday, November 7, 11
def caller_method(depth = 1) parse_caller(caller(depth+1).first).last end def parse_caller(at) if /^(.+?):(\d+)(?::in
`(.*)')?/ =~ at file = Regexp.last_match[1] line = Regexp.last_match[2].to_i method = Regexp.last_match[3] [file, line, method] end Monday, November 7, 11
What about bad tests? Monday, November 7, 11
Make sure the suite runs Monday, November 7, 11
Tests are also code Monday, November 7, 11
The 5-minute rule Monday, November 7, 11
When to refactor Monday, November 7, 11
Simple refactors can be done at any time... Monday, November
7, 11
...as long as the tests are green Monday, November 7,
11
Especially if you can’t test without refactoring Monday, November 7,
11
More complex refactors should be tied to actual new requests
Monday, November 7, 11
And in conclusion... Monday, November 7, 11
Respect working code Monday, November 7, 11
Test at as high a level as you can Monday,
November 7, 11
Leave things better than you found them Monday, November 7,
11
Isolate code under test Monday, November 7, 11
Consider the cost of change against the cost of no
change Monday, November 7, 11
railsrx.com @noelrap Rails Test Prescriptions Rate: http://bit.ly/nrmwtest Monday, November 7,
11