天天看點

《 自動化測試最佳實踐:來自全球的經典自動化測試案例解析》一一1.3 建立自動化政策

1.3 建立自動化政策

我們需要在不破壞現有功能的前提下釋出産品的新功能特性。而且,需要盡快知道一個新的代碼變動是否會引起回歸測試的失敗。手動回歸測試在每兩周的疊代後期才能給予我們回報,以至于沒有時間進行充分的回歸測試。

我們中一些人曾經在其他靈活團隊中進行過測試驅動開發(test-driven development, tdd)。我們發現tdd能幫助建立出設計良好的、健壯的代碼。

我們現有的回歸測試是手動操作的,整個團隊通過使用團隊wiki上所記錄的腳本進行手動測試。在每兩周的疊代周期中,這就花費了整個團隊的20%的時間。這些測試僅僅為程式最核心的部分提供了最小程度的覆寫。産品中報告的缺陷表明,回歸測試的失敗仍有可能發生。在每次疊代周期中,我們至少要花20%的時間修複這些産品缺陷,進而限制了我們能開發的新功能的數量。

自動化的回歸測試會帶來更高、更準确的覆寫率,這需要投入大量的時間、金錢和精力,我們可能需要硬體和軟體來建立建構過程、持續運作測試所需要的環境,我們也需要使測試實作自動化的架構和驅動。然而,我們可以計算出這一自動化将會節省我們40%的時間,利用這些時間可以進行更多有價值的活動,比如進行新的開發,是以,其收益遠大于成本。

繼續進行手動回歸測試必将會失敗,我們需要一個明确的決策來進行自動化。因為我們都在進行手動回歸測試,每個人都感受到了沒有自動化測試的痛苦。是以,我們有了解決這一問題的動力。首先,我們需要一個可測試的架構……

1.3.1 一個可測試的架構

tdd這條路是要走的,但是目前的代碼在業務邏輯、資料庫通路和ui等處相結合時,情況比較複雜,自動化單元測試也就變得很難了。往往很難隔離任何一個元件單獨進行測試。

這樣看來,似乎找到一種把軟體進行分層的新架構是非常明智的。我們開發出了這一新架構的所有新功能。

【小竅門】

不要嘗試解決老問題,進行新的開發來開展更好的實踐。

如果進行自動化測試的成本比其收益高,那麼進行自動化測試就沒什麼意義。我們研究圖1-1所示的自動化測試金字塔(這一金字塔是由我們當時的經理mike cohn提出的)。單元級别的測試一般roi最高。程式員可以很快寫出它們并運作,而且測試可以根據需要進行更新。是以可以将單元級别的測試作為自動化回歸測試的堅實基礎。

我們的業務邏輯相當複雜,而且新架構将這一邏輯從資料庫和使用者接口層中分離出來,這樣就可以通過設定記憶體中資料并在其上運作産品代碼來進行測試。這是金字塔的中間層———比底層運作的測試要少但是依然很重要。

我們還需要測試ui,但是通過ui進行的自動化測試本身就非常脆弱、維護費用高且運作緩慢。因為最終想使ui測試所占的比例盡量最小,是以它就處在金字塔的最頂端。盡管如此,與其他團隊一樣,我們從圖形使用者界面(gui)冒煙測試(smoke test)開始,來擷取一些代碼防護。是以,從這個角度,我們的金字塔是上下颠倒的,但是沒關系———最終我們會将它翻轉過來。(我們最終花了4年時間才獲得為之努力的三角形形狀!)

《 自動化測試最佳實踐:來自全球的經典自動化測試案例解析》一一1.3 建立自動化政策

解決問題的最直接途徑未必是最佳途徑。

我們現在明白了我們需要做什麼,是以我們開始着手實施那個能給我們帶來**最大實惠的任務。

1.3.2 建立建構過程**

我們隻有4位程式員,但是他們會經常檢查源代碼控制系統中的變化。我們需要確定他們沒有不小心修改别人的内容或者破壞現有的任何功能。同時,我(測試人員)有時候不得不等待好幾天,部署在測試環境中的代碼才能完成一次建構。一個自動化的建構過程(build process)将保證在每次檢入後的幾分鐘内,最新代碼的可部署版本就是可用的。

管理層向我們強調了品質是我們的第一目标,他們樂意寬限一些時間來讓我們搭建一個好的基礎結構。

【真知灼見】

好的管理者會準許團隊花時間去開發自動化的基礎結構。

我們停下正在做的事情,使用cruisecontrol和一個新的linux伺服器建立了一個持續內建(continuous integration, ci)過程。因為我們還沒有可以運作的任何測試執行個體,是以隻是簡單編譯代碼和建構可部署的二進制檔案。我可以看到每次建構的檢入檔案并能夠選擇想部署到産品中的二進制檔案。這很有用,但是還不夠。

1.3.3 擷取測試的基準:gui冒煙測試

程式員正在學習如何使單元測試自動化并編寫測試先行(test-first)的代碼,但是要真正實施測試驅動開發需要花好幾個月的時間。針對遺留代碼,使用gui冒煙測試可能是一個快速獲得自動化測試覆寫的途徑。但是使用什麼工具最好呢?

我們有購買一個付費工具的預算資金,但是團隊裡的程式員是java程式員,他們萬不得已是不願意使用另一種腳本語言來進行測試的。捕獲/回放并不适合我們,因為我們需要可維護的、穩定的測試腳本。我們選中了 cannoo webtest——一個可以讓我們修改xml檔案中的測試用例,并使用ant運作它們的開源架構。而且它很容易與我們的建構過程內建。

昂貴的商業工具不一定是最好的選擇。

我讓業務專家把需要用冒煙測試來保護的系統核心區域按優先等級進行劃分。每個沖刺時間段裡,都安排了時間讓我用webtest工具自動運作測試腳本。我們首先追求的是“快赢”,針對系統中每個使用者角色的基本功能實作自動測試。

首先, ci建構過程隻運作了少量單元測試和一些覆寫系統高得分點的gui冒煙測試。随着在這兩個級别引入更多測試,我們将gui測試移到單獨的建構過程中并隻在晚上運作,這樣,我們可以更快得到的回報資訊。

與此同時,我們将單元測試和每個新使用者故事(user story)的gui冒煙測試都放在疊代中完成。新的功能将會在自動化的單元測試和gui測試中被覆寫。一旦程式員能夠熟練使用tdd,我們就将進入金字塔的中間層。

1.3.4 在單元級别驅動開發

我們的程式員中隻有一人曾經實施過tdd,但每個人都支援這種理念。我們根據别人的介紹,找到了我們能找到的最好的顧問來幫助我們學習如何實施tdd,很多時候我們都是自帶午餐以便擠出時間來進行tdd試驗。但是很遺憾的是:它很難學!我們團隊需要時間來掌握它。

我們的管理層知道這個道理:目标是寫出優美的代碼,優美到可以拿回家給媽媽,當做冰箱貼。我們的公司——一個剛剛成立3年的商業公司,因為網絡應用問題和無能力及時釋出新功能而面臨倒閉。我們的商業合作夥伴也準備放棄我們了,但自從我們實施靈活開發(scrum)以後,他們看到了我們為提高穩定性和響應能力所做的努力。我們的執行者緻力于具有長遠收益的投資。

【經驗教訓】

一個迫在眉睫的災難可能是巨大進步的推動力。

我們知道這些單元級别的測試具有最好roi。我們也了解tdd事實上是代碼設計,而不是測試。考慮“代碼是用來做什麼的”可以幫助程式員寫出正确的代碼,而快速實施測試,才能及時地提供重要的回報資訊。

單元級别測試的最大好處就是能夠提供最快速的回報。在研究一些好的實踐之後,我們決定将代碼建構過程的時間控制在10分鐘内。這需要單元測試的随機重構。早些時候,單元測試需要通路資料庫,之後,程式員掌握了如何構造、模拟它,以及消除它的影響,使測試快速運作又能提供正确的測試覆寫。