以自動化測試撬動維護階段的遺留系統(2)

發表于:2013-01-23來源:程序員作者:胡振波點擊數: 標簽:自動化測試
這樣,我們就讓測試程序和具體的測試數據得到了解耦,緩解了測試的不可重復執行性,使其更加穩定,維護成本也得到降低。除了上述方法,還有其他方

  這樣,我們就讓測試程序和具體的測試數據得到了解耦,緩解了測試的不可重復執行性,使其更加穩定,維護成本也得到降低。除了上述方法,還有其他方式可以避免測試程序和測試數據的耦合。

  功能測試程序,是在用一種自動化的方式代替人的手工執行,但同時也一定程度上丟失了手工執行的靈活性。讓功能測試程序保持靈活應變是我們在編寫測試程序時應該考慮的一個重點。

  為遺留系統寫單元測試

  為遺留系統寫單元測試會面臨和寫功能測試不一樣的挑戰,在復雜度及對人的能力要求上也可能會更高一些。原因并不在于測試,而在于遺留系統自身。遺留系統內部 的強耦合(依賴)及每個單元的高復雜度使得測試難以開展。例如最近我接觸的幾個遺留系統,線程池邏輯和業務邏輯交織在一起,SQL拼裝邏輯、ORM邏輯和 業務邏輯也交織在一起,一個方法往往幾百上千行,而且有很深的調用鏈。

  為這樣的系統編寫單元測試,我們普遍遇到了這樣幾個問題。

  1. 私有方法如何測試:我經常被問到的一個問題是“這個私有方法怎么測”?對于私有方法的測試,可能的答案是——不要對私有方法進行測試,只要測試公有方法, 就能覆蓋到私有方法。這個答案可能正確,但在遺留系統中,往往是錯誤的。很多時候,我會反問“為什么要對私有方法進行測試?”

  下面這個例子(如圖2所示),是一個有較復雜邏輯的線程。但主要的邏輯存在于組裝和發起HTTP請求和解析返回的XML上。

  圖2 一個有較復雜邏輯的線程

  當想對私有方法進行測試時,往往意味著類過于復雜、私有方法承載著太多的職責,通過公有方法覆蓋私有方法的測試成本過高,難度太大。因此,更好的解決辦法是 分離職責、分而治之、單獨測試。通過分離職責,單獨對各部分邏輯進行測試,測試就會簡單很多,如圖3所示;另一個例子如圖4所示。

圖3 單獨對各部分邏輯進行測試

  圖4 另一個案例

  如果在不改變代碼的前提下為這樣的代碼寫測試,首先要花很多時間理解它,理清各個分支,分別為它們建立復雜的測試準備狀態等,成本很高,有時甚至為不可能完成的任務。

  2. Mock是否是遺留系統單元測試的“銀彈”:當對遺留系統進行單元測試時,Mock作為“銀彈”時不時地出現了。面對遺留系統中有較深依賴鏈的一些方法, 把那些難以建立的依賴統統Mock掉是最快的手段。但經驗告訴我:對Mock保持警惕,一旦引入它,就容易被人濫用。當然它本身無錯,錯在使用它的人,如 果一定要怪Mock,就怪有些Mock工具過于強大吧。濫用Mock會導致:

  測試真實性的減弱,降低測試程序作為測試本身的價值;

  濫用Mock的“交互驗證(Verification)”,使得測試和實現緊密耦合,降低測試的穩定性。

  我專門回顧了之前做的幾個系統,發現用到Mock的時候微乎其微,大多使用在對不受控依賴建立測試替身上。在保證測試執行速度的前提下,這是我推薦的做法。但面對遺留系統時,我們很容易把“難以建立依賴測試狀態”作為使用Mock的借口,大量濫用。

  單元測試,相對于功能測試等高層次的測試,是代碼級別的白盒測試。但之于它的測試對象而言,我們仍然應當把單元測試視為黑盒測試——單元級別的黑盒測試。例 如對一個排序方法而言,不管它采用什么排序算法實現,大多情況下我們只在乎它是否可以將一個無序數組排序。它的測試也只要基于輸入(無序數組)和輸出判斷 (有序數組)即可,就算排序算法改變,測試仍然不受影響。從這個排序方法的角度看,測試對它的內部實現不關心,是黑盒的;當內部實現改變時,只要外部行為 不變,測試就不會受到影響。濫用Mock很容易讓測試違反這個特質。

  此種情況下,我們選擇的方案是:選擇從依賴鏈的末端開始測試,從這里開始逐漸完備測試狀態準備機制。在保證測試速度(運行速度和編寫速度)的前提下,盡量避免使用Mock。當然,如果你的代碼依賴復雜、混亂,那么首先可能要重構,重新組織分配職責,簡化依賴關系。

  簡而言之,面對遺留系統進行單元測試時,有幾個值得關注的實踐:

  分離職責,分而測之,優于私有方法進行測試;

  逐步完備測試狀態準備機制,優于使用Mock。

  之前,我個人對于在遺留系統上實施測試自動化建設是總體悲觀的:遺留系統龐大,測試的效果并不會在短期內得以體現;而團隊,恰恰經常認為遺留系統足夠穩定 (沒有什么大需求,而且90%的代碼可能短期不需要改動),沒有動刀的必要。因此,大多數團隊很有可能會在看到測試帶來的效果之前就放棄了。

  但請相信我,這一切都是假象。故障頻發的正是這些遺留系統:

  穩定是假象,遺留系統里隱藏著很多故障和漏洞,只是暫時沒有爆發而已;

  穩定是假象,粗劣的設計讓任何一個需求的變化都會像霰彈一樣影響整個系統,遺留系統大都是極其脆弱的。

  而單元測試,除了它本身帶來的測試價值之外,對于遺留系統而言,更大的部分在于以下三個方面:

  驅動遺留系統的重構,提升架構設計和內部質量(遺留系統雖龐大,但壞味道其實都雷同)。這是對遺留系統而言最關鍵但一般情況下最沒有可能去做的事情;

  暴露并解決系統中的缺陷和漏洞,在這個過程中,我們發現并處理了很多漏洞和缺陷,包括多線程處理上、業務邏輯等;

  更重要的是提升團隊的重構和設計能力以及團隊質量意識,特別是內部質量。

原文轉自:http://www.programmer.com.cn/14624/

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97