在敏捷中應用測試驅動開發
在敏捷和DevOps領域,企業越來越關注持續整合和持續部署問題。他們更頻繁地更新軟體,給軟體測試造成額外的時間壓力。而測試驅動開發可以成為解決這個問題的一劑良方。
什麼是測試驅動開發?
測試驅動開發(Test-Driven Development, TDD)是一種開發方法,即在開發階段使用自動化測試。與傳統的開發方法相比,一個很大的區別是TDD要求你在開發之前先編寫測試 。
TDD似乎只與軟體測試有關,但這並不是它的最終目的。TDD的目標是通過自動化的方式來演化系統,以滿足所有的功能和非功能性需求。
經常會被提及的另一個術語是KISS原則。KISS是“Keep It Simple, Stupid”或“Keep It Simple and Straightforward”的縮寫。這個原則的核心思想是儘可能用最少的精力來解決給定的問題(或挑戰)。
那麼TDD看起來是怎樣的?
要正確使用TDD方法,最好先搭建一個初始的軟體架構。我說的不一定是巨集偉的架構設計,但至少是一個粗略的架構。
當然,也要看你都做了哪些架構決策。在某些情況下,你不想編寫單元測試,因為它會降低程式碼的質量,或者測試用例太過複雜。你可以改為編寫自動化的場景或整合測試。關鍵是要對它們進行自動化。在以下步驟中,我假設它們是單元測試。
- 確定合理的測試用例;
- 確定測試條件;
- 編寫一個骨架類(只有方法簽名),讓程式碼可以通過編譯;
- 編寫測試程式碼;
- 執行測試(它應該會失敗);
- 花最少的工作量讓測試用例可以執行;
- 執行自動化測試;
- 重構程式碼;
- 再次執行自動化測試,保證軟體仍然可以正常執行;
- 重複,直到符合產品待辦事項(使用者故事)的驗收標準。
第1步:確定合理的測試用例
第一步是確定要編寫的第一個測試是什麼,你需要考慮到依賴關係。首先,你要實現你所依賴的變更。
第2步:確定測試條件
一個單元測試由三部分組成:Arrange、Act和Assert。為了確保只實現所需的內容,你要知道方法的前置和後置條件。
比如有這樣的一個使用者故事:
作為使用者,我只想安排沒有衝突的預約,這樣就不會讓客戶失望。
在這個使用者故事中,使用者只想要沒有衝突的預約。有五種情況可能會讓新的預約產生衝突。
- 新預約的開始時間處於現有預約的時間範圍內;
- 新預約的結束時間處於現有預約的時間範圍內;
- 現有預約的開始和結束時間段處於新預約的開始和結束時間段內;
- 新預約的開始和結束時間段處於現有預約的開始和結束時間段內;
- 新預約的開始和結束時間與現有預約完全一樣。
在進行單元測試期時,你檢查所有這些條件,以及方法的預期結果。
第3步:編寫一個骨架類(只有方法簽名),讓程式碼可以通過編譯
這一步並不是正式TDD的一個步驟,不過這樣做可以給我們帶來方便,因為後續我們就可以利用程式碼自動完成。
你將建立一個類(如果它是新的)和它的方法,但先不要實現任何功能程式碼。
第4步:編寫測試程式碼
現在可以編寫實際的測試程式碼了,可以遵循Arrange、Act、Assert這樣的結構。
- Arrange:設定環境(如樁和測試資料),這樣就可以斷言你的測試方法。
- Act:呼叫方法!
- Assert:檢查結果、樁等等。
第5步:執行測試(它應該會失敗)
執行之前建立的測試,預期的結果是測試無法通過。如果它執行成功了,你必須回到第4步。
第6步:花最少的工作量讓測試用例可以執行
接下來是程式碼時間!但是有一個問題,你必須用盡可能少的程式碼讓測試執行通過。
對於第2步中的預約使用者故事,還沒有用於檢查錯誤日期的測試,這就是為什麼之前先不實現它。
第7步:執行所有的自動化測試
寫完程式碼並通過測試後,就可以再次執行所有的自動化測試。新增加的程式碼不應該破壞已有的構建或導致其他測試失敗。
如果出現其他測試失敗,請務必做出修改,讓所有測試可以再次通過。
第8步:重構程式碼
在執行完所有的自動化測試(全部通過)之後,可以開始對程式碼進行重構了。
這次應該把重心放在程式碼質量上。檢查程式碼是否符合編碼指南和規範,刪除重複的程式碼,在不清晰的地方添加註釋。另外,新增用於生成文件的註釋。
還有一點不要忘了,看看當前的解決方案是否仍然是能夠解決問題的最簡單的解決方案。
第9步:再次執行自動化測試,保證軟體仍然可以正常執行
再次執行所有測試,確保在重構程式碼後所有測試仍然可以通過。
如果在程式碼重構後有測試失敗,就要做出必要梗概,再次讓所有測試都通過。
第10步:重複,直到符合待辦事項(使用者故事)的驗收標準
在前面的步驟中,你可能一次實現了一個或多個方法。在這一步,你需要驗證是否滿足產品待辦事項或使用者故事所指定的驗收標準。
如果符合驗收標準,那麼你的任務就完成了。如果沒有,請從頭開始重複所有步驟。
檢視英文原文:ofollow,noindex" target="_blank">https://myhomebase.nl/2018/09/test-driven-development-in-an-agile-world/
感謝張嬋對本文的審校。