因此,最合理的引入測試的階段是在需求階段。需求階段的測試工作的重點是如何定義測試計劃,如何定義接受測試并獲得客戶的認可,在需求階段結束的時候,必須保證所有的需求都是可測試的,都擁有測試用例,需求階段另一個重要的測試任務是準備構建測試沙盒,建立一個測試環境,以及這個軟件項目所需要的測試數據;在設計階段,測試工作的重點則在于如何定義各個模塊的詳細測試內容,最好的方式是實現測試代碼,并構建測試框架,對于一些比較復雜的項目,甚至還需要編寫一些測試工具。實踐中我們發現,在XUnit的基礎上擴展出一個測試框架是一種簡單但又實用的方法。XUnit的重點是對自動化測試提供了一個通用的框架,捕獲異常,記錄錯誤和失敗,并利用組合模式對Test Case和Test Suite進行管理。實際上,還有很多工作是可以在XUnit框架上繼續開展的,例如,軟件開發中是不是存在較為通用的測試用例?這樣,你就可以定義一些抽象的測試用例,并以此作為測試框架的基礎。再比如,我們希望每天晚上在進行日集成的時候,測試結果能夠通過短信直接發送到負責人的手機上,那么我們可以在框架中嵌入這部分的功能。這些都屬于對測試框架的積累。對一個軟件組織來說,很有必要花費時間對測試框架進行積累。這可以簡化測試的工作量,并提升軟件的質量。
測試過程
我們一開始說,測試有其自己的過程,雖然XP并沒有花費太多的筆墨來描述自己的測試過程,但經過細心的觀察,我們可以發現,在XP中同樣存在著一個測試過程:
這個過程是從用戶故事(或者是我們在上一章中推薦的用例)開始的,用戶故事不但為版本計劃提供了需求,而且為接受測試提供了測試場景。而對于客戶參與的接受測試來說,它為每一次的迭代提供了反饋,包括bug的反饋和下次迭代信息的反饋。只有客戶認可了接受測試,軟件才能夠發布小版本。這是XP過程最高層次的測試過程。
在上文中,我們提到引入測試最好的時機是在需求分析階段。因為測試生命周期的起源活動-測試計劃和測試用例都需要需求的支持。我們再參考RUP的過程:
我們看到,RUP建議在先啟階段就開始測試活動。在開發過程的前期就進行測試活動,其目的是為了提高軟件的可測試性。軟件設計如果沒能夠考慮軟件的可測試性,那么測試的成本就會升高,軟件質量隨之下降。有時候,單元測試或是組件測試是很難進行的。因此,我們需要專門針對類或組件的可測試性進行測試。例如,對于一個實現企業流程的組件,之間涉及到大量的狀態、事件、分支選擇等等因素。對這樣的組件進行組件測試的代價是非常高的。如果能夠在組件設計的時候,能夠考慮到測試性,例如,將組件拆分為粒度更小的子組件,或是在組件中內嵌供測試使用的方法,能夠直接操縱組件的狀態。在設計時充分考慮可測試性,是降低測試成本的關鍵。而設計測試的源泉,正是先啟階段中對需求的分析。對流程組件測試的依據,正是源于項目涉眾對流程的需求。
測試的一些實踐問題
嚴格按照先維護測試,再維護代碼的順序要實現變更。在實踐中,測試優先常常發生的一個問題是,設計變更影響到測試代碼的時候,開發人員往往會繞過測試代碼,直接修改代碼。
在剛剛接觸測試優先思路的時候,我嚴格按照先寫測試的做法編寫代碼,但是當代碼需要修改時,有時候只是一些非常小的修改,這時候我仍然保持原有的習慣,直接對代碼進行了修改,在完成代碼的修改之后,我突然意識到測試代碼需要修改,于是我又修改了代碼,由于只是一個小修改,我認為沒有必要再運行測試了。這件事情很快被我遺忘了,但隱患就此埋下。到了兩天后的集成測試時,測試程序捕捉到了這段代碼的錯誤,經過調試,發現當時認為簡單的修改忽略了一種極端的情況。定位錯誤,調試代碼,并通過測試的時間遠遠超過了當初貪圖省事節省的時間。所幸的是,代碼在下一個檢查點(集成測試)被發現出來。 完善測試網。在我學習并實踐測試優先的時候,我所處的團隊正處于項目的中期,已經有大量的沒有實現測試的代碼被創建出來,當時我采取的思路是,新編寫的代碼必須遵循新的測試方法,舊有的代碼保持現狀。這樣做可以節省一定的成本,但是很快我們發現,投入力量把現有的代碼加上測試是絕對值得的。加上測試的代碼能夠迅速回應變化,僅僅這一點,就值得我們重建測試網。此外,由于需要構建測試,我們還發現了原有代碼中一些接口定義不合理或是不規范的地方。 而在另一些一開始就采用測試優先思路的項目中,往往遇到的問題是,隨著項目的進展,后期的測試代碼越來越優秀。這時候,我們需不需要對原有的測試代碼進行改進呢?答案是肯定的,你一定會從中獲益的,對于自動化測試來說,修改測試代碼并重新運行測試的代價并沒有你想象中的那么大。
文章來源于領測軟件測試網 http://www.kjueaiud.com/