[91大的TDD課程心得] Refactoring

Unit Test 在使用 TDD 開發時,除了單元測試的角色之外

更像是需求的描述者

但回歸到真正的實務情境上,往往遇到的不是從無到有的開發

而是從既有的架構中去新增額外的功能

於此, Unit Test 更像是重構時的保險裝置

 

在練習的範例中,重構大略可以條列為下列步驟:

  1. 測試包覆:使用維度更大的測試包覆需要重構的部份
  2. 驅動測試:使 Visual Studio 可以驅動上述測試
  3. UI邏輯分離:加上註解,使用 DTO 技巧分離 UI 與邏輯
  4. 功能分拆:重新構築函式,將維度不同或重複的程式碼分離為子函式
  5. 主動詞分離:用物件導向的角度讓「主詞」「進行」某個動作
  6. 單元測試:對於第 6 點的動作撰寫 Unit Test
  7. 實作介面:讓第 5 點「主詞」的物件們實做同一個 Interface
  8. 蓋工廠:透過工廠依據不同條件產出「主詞」物件

重構是一個按部就班的過程,一次一個動作

每個步驟執行完畢之後,都跑一次測試,確保行為正確

就算沒有完成到最後一個步驟,它仍然是個可以正常使用的程式碼

不影響其功能,反應到開發流程中,這就是敏捷開發運行的基石
 

重構過程中切忌同時加入需求,一次僅做一件事,按部就班,穩紮穩打才是上策!


這個例子我一做了三次,有一種練拳的感覺

基本的套路練熟之後,當我實際運用在現實的複雜案例中

真的好像明白了什麼,打通了某些關節

 

真實的案例是要加上新需求時,必須進行某種程度的重構

當我想要加上高維度的 UI 測試,發現實在太費時,光是軟體啟動就要一兩分鐘

這完全不符合 Fast 的原則,就算能夠測試,也無法方便驗證每個重構步驟

破壞意圖導向的設計流程

 

於是我捨棄了這個層面的測試方式~

重新思考這個測試的意義與價值,與其驗證目的為何

目的是要確保我重構某個 function 時,其行為與原來相同的測試保護

所以我先謹慎小心的進行最小部份有把握的重構(抽離某些簡單的相依性)

然後對這個要重構的 function 設計不少單元測試,作為我的測試保護

接著運用上述範例練習的一些技巧,開始逐步的進行重構工程

每個重構步驟完成後,都執行一開始建立的單元測試驗證其正確性

確保重構過程無誤,當重構工程結束後,再行加入新的功能。

收工!

 

在重構過程中,遇過了幾次紅燈,實在令人興奮

自己架設的保護網好像起了作用,試想這樣的錯誤,若發行出去

何年何月才會被發現,被發現後要再花多少時間除蟲才能找到問題

有 Unit Test 保護的重構,真的會比較慢嗎?似乎不會喔~