SlideShare a Scribd company logo
1 of 21
Download to read offline
Practice: Refactor with Tests
http://tech.manic.tw
2013/05/14 Ruby Tuesday@Taipei
13年5月15⽇日星期三
About Me
• Manic Chuang
• http://www.facebook.com/manic.chuang
• http://tech.manic.tw
• PIXNET
• Rails / PHP
13年5月15⽇日星期三
⼤大綱
• 簡單介紹:Refactor 與 Testing
• 重點:在實務上導⼊入 Refactor 與 Testing 的經驗談
13年5月15⽇日星期三
Refactor
• To restructure software by applying a series of refactorings without
changing its observable behavior.
• 在不改變程式外在⾏行為的情況下改進程式內部的架構
13年5月15⽇日星期三
Benefit?
• 程式更好維護
• 和測試結合 -- 讓你的開發流程更安⼼心
• ⼀一個有良好架構以及測試的專案對於新 Feature 的接受度遠⾼高於
那些所謂“年久失修”的專案
13年5月15⽇日星期三
How to learn?
• Starter: 7 Patterns to Refactor Fat ActiveRecord Models
• Further: Refactoring: Improving the Design of Existing Code
13年5月15⽇日星期三
Tests
• “重構之前,⾸首先檢查⾃自⼰己是否有⼀一套可靠的測試機制。這些測
試必須有⾃自我檢驗 (self-checking) 能⼒力”
• 如果你在重構時沒有包含測試,不只是這個重構可能會引來更
多的 Bug 的問題 ﹣ 你可能會過度追求完美,導致不知如何停
⼿手。
13年5月15⽇日星期三
It’s hard to begin.
• Refactor code 就是改動程式碼,改動就有可能出錯,⽽而沒有⼈人
希望⼀一個正常運⾏行的 production site 因為改爛 code ⽽而 crash 掉
• 為了不出錯,要準備好相對應的測試,以確保程式碼不會出
錯。
• 由以上兩點來講那就是會花上許多時間
• ⽽而這個花上許多時間的結果並不是實作了⼀一個新功能
13年5月15⽇日星期三
Refactor 的兩⼤大難關
• I was refactoring code that no one had asked me to work on
我在重構⼀一段沒⼈人叫我去改的程式碼
• I found it too hard to put tests in place, so I did it without them.
Which, naturally, broke some things
我發現實在太難加上測試了,所以我就沒測它,然後就有東⻄西
爛掉了
Reference: How do you stop yourself from refactoring working but awful code?
13年5月15⽇日星期三
Change your situation
• 為了要加上這個新的 Feature,我們原本的程式碼架構需要配合
做出⼀一些調整...
• When you need to refactor code you are supposed to work on,
have tests in place, but they don't have to be automated.
我需要重構這段程式碼,因為很難寫⾃自動化測試碼,所以我找
⼈人來做QA
13年5月15⽇日星期三
Situation
• ⼀一個牽涉到⾦金流交易的網站,它現在有了BUG,必須要儘快修
復。
• 同時有新的⼤大 Feature 要上
• 網站當時就很趕⼯工上來的,⽽而且經過上線後連續幾個月的⼩小
Feature 增/減,程式碼架構越來越複雜
• 時間當然有夠趕
13年5月15⽇日星期三
⽼老闆要求上線時不能再有這些BUG,
⼀一個BUG的損失要你賠⼀一千萬(誤)
13年5月15⽇日星期三
溝通
• Staging Server:要求經過⾜足夠⼈人⼯工測試後再上到 production
server.
• “如果你發現⾃自⼰己需要為程式添加⼀一個特性,⽽而程式碼結構使你
無法很⽅方便地那麼做,那麼就先重構那個程式,使特性的添加
⽐比較容易進⾏行,然後再添加特性。”
13年5月15⽇日星期三
步驟
• 共識:QA 是為了確保團隊能夠⼀一起擔負責任。如果今天有了
BUG不是程式設計師⼀一個⼈人的錯誤。
• 讓 Refactor 同時帶著⼀一些新的東⻄西:“我弄了⼀一個新的寫法程式
碼會變好維護⼀一點,⿇麻煩幫忙驗收⼀一下” 這句話是不是哪裡怪
怪的?
13年5月15⽇日星期三
Questions
• 我們怎麼確認這個 Refactor Pattern 適合我們現在的狀況?
• 要如何確認是否過度或是不⾜足?
13年5月15⽇日星期三
Example: AuctionService
• 商品有起標⾦金額,使⽤用者下標後所增加⾦金額為1元(可設定,範
圍為1~10)
• 使⽤用者每下⼀一次標需要耗⽤用點數1點(可設定,範圍為1~10)
• 在商品結標前,若有競標者下標,計時器將⾃自設定時間開始重
新倒數(25秒預設)
• 使⽤用者每下⼀一次標有20%機率可以獲得回饋1點
13年5月15⽇日星期三
Extract Service Objects
• The action is complex
• The action reaches across multiple models
• The action interacts with an external service
• The action is not a core concern of the underlying model
• There are multiple ways of performing the action
13年5月15⽇日星期三
Refactor: AuctionService
class Auction
def bid_by(user)
return false unless user.can_bid?(self)
user.consume_points
self.update_price_and_time
self.set_winner(user)
user.save_weekly_bid_count
user.check_if_lucky_bid
self.auction_logs.create
end
end
class AuctionService
def initialize(auction, user)
@user = user
@auction = auction
end
def bid!
return false unless user_can_bid?
consume_user_points
update_auction_price_and_time
set_auction_winner
set_user_weekly_bid_count
check_user_if_lucky_bid
generate_logs
end
end
13年5月15⽇日星期三
Compare
• auction.bid_by(user) 也可以寫為 user.bid(auction),讓⼈人困惑。
• 原本被拆分為兩個 model 上的測試,現在全部集中在
AuctionService 這個 model 上了
• 只要看 AuctionService 的測試內容就可以完整明⽩白此規格的要求
• 原本 model 帶著許多只有在特定時候才會⽤用到的 method,拆出
去後這兩個 model 都變“輕”許多
13年5月15⽇日星期三
How Tests help you Refactor
• 最基本的幫助:你可以不⽤用擔⼼心改錯程式碼
• ⼀一個好的測試規格可以幫助你找到 Bad Smell
• 不⽤用硬是想著要⾃自動化測試。
Any effective test is better than no test at all.
13年5月15⽇日星期三
Thank you.
13年5月15⽇日星期三

More Related Content

What's hot

Web前端测试
Web前端测试Web前端测试
Web前端测试kriy
 
用Maven管理專案的依賴關係
用Maven管理專案的依賴關係用Maven管理專案的依賴關係
用Maven管理專案的依賴關係Huang Bruce
 
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具美团点评技术沙龙06 - 提高移动端兼容性测试效率工具
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具美团点评技术团队
 
Angular 5 全新功能探索 @ JSDC2017
Angular 5 全新功能探索 @ JSDC2017Angular 5 全新功能探索 @ JSDC2017
Angular 5 全新功能探索 @ JSDC2017Will Huang
 
React基礎教學
React基礎教學React基礎教學
React基礎教學昇倫 蔡
 
Show Me The Page - 介紹 Critical rendering path
Show Me The Page - 介紹 Critical rendering pathShow Me The Page - 介紹 Critical rendering path
Show Me The Page - 介紹 Critical rendering pathYvonne Yu
 
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程twMVC
 
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格Will Huang
 
twMVC#29 | 當.Net Core 遇到AWS Lambda
twMVC#29 | 當.Net Core 遇到AWS LambdatwMVC#29 | 當.Net Core 遇到AWS Lambda
twMVC#29 | 當.Net Core 遇到AWS LambdatwMVC
 
Angular 靜態網站產生器不求人:Scully 新手入門
Angular 靜態網站產生器不求人:Scully 新手入門Angular 靜態網站產生器不求人:Scully 新手入門
Angular 靜態網站產生器不求人:Scully 新手入門志龍 陳
 
Javascript template & react js 初探
Javascript template & react js 初探Javascript template & react js 初探
Javascript template & react js 初探wantingj
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC
 
测试驱动的前端开发初探
测试驱动的前端开发初探测试驱动的前端开发初探
测试驱动的前端开发初探hua qiu
 
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角twMVC
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)Will Huang
 
React js入門教學
React js入門教學React js入門教學
React js入門教學TaiShunHuang
 

What's hot (16)

Web前端测试
Web前端测试Web前端测试
Web前端测试
 
用Maven管理專案的依賴關係
用Maven管理專案的依賴關係用Maven管理專案的依賴關係
用Maven管理專案的依賴關係
 
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具美团点评技术沙龙06 - 提高移动端兼容性测试效率工具
美团点评技术沙龙06 - 提高移动端兼容性测试效率工具
 
Angular 5 全新功能探索 @ JSDC2017
Angular 5 全新功能探索 @ JSDC2017Angular 5 全新功能探索 @ JSDC2017
Angular 5 全新功能探索 @ JSDC2017
 
React基礎教學
React基礎教學React基礎教學
React基礎教學
 
Show Me The Page - 介紹 Critical rendering path
Show Me The Page - 介紹 Critical rendering pathShow Me The Page - 介紹 Critical rendering path
Show Me The Page - 介紹 Critical rendering path
 
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程
twMVC#21 | 以實例說明ASP.NET Web API 服務的開發與測試過程
 
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格
保哥線上講堂:利用 StyleCop 撰寫一致的 C# 程式碼風格
 
twMVC#29 | 當.Net Core 遇到AWS Lambda
twMVC#29 | 當.Net Core 遇到AWS LambdatwMVC#29 | 當.Net Core 遇到AWS Lambda
twMVC#29 | 當.Net Core 遇到AWS Lambda
 
Angular 靜態網站產生器不求人:Scully 新手入門
Angular 靜態網站產生器不求人:Scully 新手入門Angular 靜態網站產生器不求人:Scully 新手入門
Angular 靜態網站產生器不求人:Scully 新手入門
 
Javascript template & react js 初探
Javascript template & react js 初探Javascript template & react js 初探
Javascript template & react js 初探
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure Functions
 
测试驱动的前端开发初探
测试驱动的前端开发初探测试驱动的前端开发初探
测试驱动的前端开发初探
 
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角
twMVC#25 | ASP.NET MVC A/B Testing 的眉眉角角
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)
 
React js入門教學
React js入門教學React js入門教學
React js入門教學
 

Similar to Practice: Refactor with Tests

Bruce-輕鬆上手Asp.net web api 2.1.2
Bruce-輕鬆上手Asp.net web api 2.1.2Bruce-輕鬆上手Asp.net web api 2.1.2
Bruce-輕鬆上手Asp.net web api 2.1.2Study4TW
 
輕鬆上手ASP.NET Web API 2.1.2
輕鬆上手ASP.NET Web API 2.1.2輕鬆上手ASP.NET Web API 2.1.2
輕鬆上手ASP.NET Web API 2.1.2Bruce Chen
 
Blazor in NET 8 的重大改變___________________
Blazor in NET 8 的重大改變___________________Blazor in NET 8 的重大改變___________________
Blazor in NET 8 的重大改變___________________Gelis Wu
 
How to ASP.NET MVC4
How to ASP.NET MVC4How to ASP.NET MVC4
How to ASP.NET MVC4Daniel Chou
 
Agile introduction
Agile introductionAgile introduction
Agile introductionJen-Chieh Ko
 
雪球服务化实践历程.Print
雪球服务化实践历程.Print雪球服务化实践历程.Print
雪球服务化实践历程.Printfulin tang
 
Test driven-frontend-develop
Test driven-frontend-developTest driven-frontend-develop
Test driven-frontend-developfangdeng
 
91APP: 從 "零" 開始的 DevOps
91APP: 從 "零" 開始的 DevOps91APP: 從 "零" 開始的 DevOps
91APP: 從 "零" 開始的 DevOpsAndrew Wu
 
01 DevOps and Azure DevOps overview
01 DevOps and Azure DevOps overview01 DevOps and Azure DevOps overview
01 DevOps and Azure DevOps overviewAlan Tsai
 
Mobile app的測試v2
Mobile app的測試v2Mobile app的測試v2
Mobile app的測試v2Mr PM
 
2012 China 软件测试大会
2012 China 软件测试大会2012 China 软件测试大会
2012 China 软件测试大会mayun1688
 
互联网持续交付整形记
互联网持续交付整形记互联网持续交付整形记
互联网持续交付整形记Ryan YU
 
Growing object oriented system
Growing object oriented systemGrowing object oriented system
Growing object oriented systemxprayc
 
Continuous Delivery: automated testing, continuous integration and continuous...
Continuous Delivery: automated testing, continuous integration and continuous...Continuous Delivery: automated testing, continuous integration and continuous...
Continuous Delivery: automated testing, continuous integration and continuous...Jimmy Lai
 
微博推荐引擎架构蜕变之路
微博推荐引擎架构蜕变之路微博推荐引擎架构蜕变之路
微博推荐引擎架构蜕变之路Fan Robbin
 
Mock Server的应用与实践
Mock Server的应用与实践Mock Server的应用与实践
Mock Server的应用与实践qi lei
 
Top100summit 游戏中的自动化测试 - 金山 - 白银祖
Top100summit 游戏中的自动化测试 - 金山 - 白银祖Top100summit 游戏中的自动化测试 - 金山 - 白银祖
Top100summit 游戏中的自动化测试 - 金山 - 白银祖drewz lin
 
Top100summit前端的云时代支付宝前端平台架构 王保平
Top100summit前端的云时代支付宝前端平台架构  王保平Top100summit前端的云时代支付宝前端平台架构  王保平
Top100summit前端的云时代支付宝前端平台架构 王保平drewz lin
 
The way to continuous delivery
The way to continuous deliveryThe way to continuous delivery
The way to continuous deliveryQiao Liang
 
Rails 炸機實務
Rails  炸機實務Rails  炸機實務
Rails 炸機實務Manic
 

Similar to Practice: Refactor with Tests (20)

Bruce-輕鬆上手Asp.net web api 2.1.2
Bruce-輕鬆上手Asp.net web api 2.1.2Bruce-輕鬆上手Asp.net web api 2.1.2
Bruce-輕鬆上手Asp.net web api 2.1.2
 
輕鬆上手ASP.NET Web API 2.1.2
輕鬆上手ASP.NET Web API 2.1.2輕鬆上手ASP.NET Web API 2.1.2
輕鬆上手ASP.NET Web API 2.1.2
 
Blazor in NET 8 的重大改變___________________
Blazor in NET 8 的重大改變___________________Blazor in NET 8 的重大改變___________________
Blazor in NET 8 的重大改變___________________
 
How to ASP.NET MVC4
How to ASP.NET MVC4How to ASP.NET MVC4
How to ASP.NET MVC4
 
Agile introduction
Agile introductionAgile introduction
Agile introduction
 
雪球服务化实践历程.Print
雪球服务化实践历程.Print雪球服务化实践历程.Print
雪球服务化实践历程.Print
 
Test driven-frontend-develop
Test driven-frontend-developTest driven-frontend-develop
Test driven-frontend-develop
 
91APP: 從 "零" 開始的 DevOps
91APP: 從 "零" 開始的 DevOps91APP: 從 "零" 開始的 DevOps
91APP: 從 "零" 開始的 DevOps
 
01 DevOps and Azure DevOps overview
01 DevOps and Azure DevOps overview01 DevOps and Azure DevOps overview
01 DevOps and Azure DevOps overview
 
Mobile app的測試v2
Mobile app的測試v2Mobile app的測試v2
Mobile app的測試v2
 
2012 China 软件测试大会
2012 China 软件测试大会2012 China 软件测试大会
2012 China 软件测试大会
 
互联网持续交付整形记
互联网持续交付整形记互联网持续交付整形记
互联网持续交付整形记
 
Growing object oriented system
Growing object oriented systemGrowing object oriented system
Growing object oriented system
 
Continuous Delivery: automated testing, continuous integration and continuous...
Continuous Delivery: automated testing, continuous integration and continuous...Continuous Delivery: automated testing, continuous integration and continuous...
Continuous Delivery: automated testing, continuous integration and continuous...
 
微博推荐引擎架构蜕变之路
微博推荐引擎架构蜕变之路微博推荐引擎架构蜕变之路
微博推荐引擎架构蜕变之路
 
Mock Server的应用与实践
Mock Server的应用与实践Mock Server的应用与实践
Mock Server的应用与实践
 
Top100summit 游戏中的自动化测试 - 金山 - 白银祖
Top100summit 游戏中的自动化测试 - 金山 - 白银祖Top100summit 游戏中的自动化测试 - 金山 - 白银祖
Top100summit 游戏中的自动化测试 - 金山 - 白银祖
 
Top100summit前端的云时代支付宝前端平台架构 王保平
Top100summit前端的云时代支付宝前端平台架构  王保平Top100summit前端的云时代支付宝前端平台架构  王保平
Top100summit前端的云时代支付宝前端平台架构 王保平
 
The way to continuous delivery
The way to continuous deliveryThe way to continuous delivery
The way to continuous delivery
 
Rails 炸機實務
Rails  炸機實務Rails  炸機實務
Rails 炸機實務
 

Practice: Refactor with Tests