人工審查
針對每一項變更,問:它服務於哪項需求、改變了哪些行為,以及是否有現有機制可以做到?
僅供審查的請求不授權編輯。請遵循專案的慣例和使用者的範圍,包括測試與發布限制。
追蹤行為
比較新舊執行路徑,包括呼叫者和繞過分支。區分傳遞物件、傳遞工廠和執行它。確定誰擁有狀態、何時載入,以及哪些操作會看到替換。
在移除重複程式碼前先調查其由來。哪個先前的變更讓這個操作變得必要?一個新的實作可能遺失了隱含的啟動檢查或清理。在聲明某項工作執行兩次之前,先驗證分支。
檢查失敗時機、重試、資源清理,以及原始原因是否傳遞給使用者。一個從啟動階段移動到連線設定的錯誤,即使兩個路徑最終都會失敗,仍然可能改變行為。在將內部例外類型視為相容性需求之前,先檢查它的消費者。
簡化責任層
首先檢查接收元件已經支援哪些功能。如果它的契約足夠,就修正呼叫者提供的內容,而不是為接收者增加另一個責任。不要僅僅為了讓呼叫者看起來相似,就把工作移入共用的建構子。
為每個新增的操作、欄位、分支或抽象層提供當前任務的正當理由。對於移除,檢查依賴它的呼叫者和保證。優先選擇現有的相容契約;保留那些執行有意義轉換或強制執行契約的適配器。
沿著整個受影響路徑追蹤狀態和工作。移除快取並不能修復過時狀態,如果呼叫者在閉包中捕獲了相同的值。相反地,一個動態提供者和一個基於檔案的備援可能故意在不同時間載入。將它們統一可能會引入回歸。
透過讀者必須追蹤的概念、狀態擁有者和間接層次來判斷簡潔性。一個較小的差異並不總是更清晰的設計。避免不相關的格式化和為未來任務做準備。
測試需求
每個測試應該透過其名稱、輸入、動作和預期結果來講述一個連貫的案例。僅保留建立該案例所需的設定和斷言。當保證需要它們時(例如失敗後的復原),多個階段可以放在一起;不相關的案例則不應放在一起。
保留能夠區分所需行為和回歸的最小集合。僅當內部呼叫次數表達了某項需求(例如只載入一次)時,它才重要。確認注入的失敗確實發生了:單靠逾時或關閉的 socket 可能會因為錯誤的原因而通過測試。
按相關行為對測試排序,讓讀者攜帶有用的上下文進入下一個測試。使用具體的名稱,而不是解釋性的註解。將註解視為首先改善程式碼的提示;保留那些無法在名稱或結構中清楚表達的理由。
在新增自訂的 Fixture、等待、斷言或資源輔助函式之前,先尋找現有的框架或基底類別功能。優先選擇直白的程式碼。當共用的重複設定保持可理解時,可以共用;但讓場景特定的輸入和動作保持可見。避免使用回呼、旗標或通用輔助函式,因為它們透過隱藏案例來節省行數。
在斷言所需的事件上進行同步,而不是在延遲或另一個執行緒中的較早事件上。在失敗時保留清理。按順序閱讀最終的測試,不看差異,檢查其目的是否在沒有對話的情況下依然清晰。
說明與交付
保留那些解釋不明顯原因並防止合理錯誤簡化的註解。移除對明顯操作的敘述。保持 API 契約精確且使用者指令可操作;在不看差異的情況下閱讀已編輯的段落,檢查它們是否能夠獨立存在。
將使用者的診斷和你自己的第一印象都視為假設。報告有支援的發現,包括觸發場景、後果、證據和最小的有用修正。將缺陷與開放性問題和可選改進分開。沒有發現也是一個有效的結果。
對於重大的重新設計,解釋一個具體的執行方式、哪些部分變得更簡單,以及行為或相容性的成本。在約定範圍之外解決選擇時與使用者確認;繼續常規授權的修復,不需要再次批准。
在修復之後,閱讀完整的受影響流程和最終的差異。報告結論、執行的檢查和剩餘的差距,而不是為每一行敘述一個問題。