測試觀念談

測試觀念談

鄧 輝<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

到目前爲止,測試仍然是一種公認的檢驗程序正確性最爲有效的手段。詳盡的測試可以大大地降低程序的缺陷率。雖然缺陷率是目前一種公認的檢驗程序質量的指標,但是它只是一個結果,要到達大家都滿意的一個指標值是要付出一定的代價的。

 

糟糕的是,有很多項目在進行測試時,都只把注意力放在了這個缺陷率和覆蓋率結果上,他們編寫了非常詳盡的測試用例文檔,然後根據這個用例文檔編寫出對應的測試代碼進行測試。這種做法在軟件需求穩定的情況下也許能夠工作的不錯,但是需求不斷變化這個大家都不願意看到卻又無法避免的現實,給這種測試方法帶來了巨大的打擊。功能的增加、修改和bug的修正都不可避免地導致程序結構的變化,而這種只關注覆蓋率的測試用例文檔和測試代碼必然嚴重依賴於程序的結構。結果自然不難想象,他們不僅要去更改程序結構,還得去更改測試代碼,即使在所要求的程序功能沒有改變時也是如此。更加糟糕的是,他們還得去更改測試用例文檔,以保持其和測試用例代碼以及要測試的代碼一致。否則的話,這份文檔就會變得過時,此時非但不會具有什麼用於交流的好處,反而會變得危險。

 

爲什麼會出現這種結果呢?難道說他們關注覆蓋率錯了嗎?關注覆蓋率本身沒有錯誤,但是由於他們把覆蓋率、缺陷率和軟件其他特性(其中最爲主要的一個就是封裝性)的關係割裂開來,而這種割裂必然會帶來高昂的測試代價。一個具有糟糕變化率封裝特性的代碼,很可能不論你付出多少代價,也根本無法達到高的測試覆蓋率。這就是軟件熵的懲罰。

 

所以我們要想在保證覆蓋率和缺陷率的前提下,降低測試的代價,進行有效的測試,我們就必須把關注點放在軟件的其他內在質量上面,我認爲最爲重要的幾個指標是:封裝性水平、變化率隔離水平、依賴關係處理水平以及是否滿足Once and Only Once原則。這些指標會大大增強軟件的靈活性和易更改性,並會大大提高軟件本身的可測試性,直接降低到測試的代價和質量。

 

其實,爲了能夠和前面提到的需求易變特性相適應,很多探索者除了提出一些有助於達成上面所說的質量指標的技術(比如:OOAOPIOC以及語言的動態性等)外,還提出了很多在軟件開發時可以遵循的一些過程方法,其中迭代法是目前得到普遍認可的一種方法。同樣,我們所掌握的技能直接決定了我們想要實施的過程方法會帶來的結果。一個沒有掌握OO技能的團隊,很可能會在實施迭代法時受到嚴重打擊。因爲和測試一樣,他們缺乏保持軟件“軟性”所需要的足夠技能。

 

說了這麼多,我主要想表達的就是希望我們不要孤立地去談測試,而是要認識到開發者本身的開發技能和測試有效性之間的關係。提高測試有效性(包括提高過程實施的有效性)的根本途徑就是提高開發人員的技能。這個技能不是他們編寫代碼快慢的能力,而是他們對於好的代碼和壞的代碼的識別能力。這樣才能非常經濟地從根源上大幅提升軟件的質量和開發生產力。我們在選擇過程方法和實踐時,要根據自己團隊的情況,有針對性的選擇那些對提升團隊當前開發技能有幫助的部分。

 

那麼團隊應該如何開始呢?我覺得TDDTest-Driven Development)是一個很好的起點,通過TDD的實踐,我們可以提高我們的分析、設計能力,改善編程的風格(注意不是編程規範),可以提高我們的快速迭代和節奏控制能力,可以提高我們對code smell的識別和重構能力,最爲重要的是可以提高我們對需求的理解和快速驗證能力(也就是我們做正確的事情的能力)。這些能力是我們能夠更爲有效地實施測試和迭代所必須的。敏捷方法中有很多實踐存在爭議,但是TDD是唯一一個得到廣泛認可的實踐。最近MSDN TV在對《Code Complete》(第2版)的作者Steve McConnell採訪時,問到如果作者要對《Rapid Development》一書進行修訂的話,會更改那些內容,Steve McConnell說,到目前爲止唯一會更改的就是增加進TDD這項最佳實踐。

 

TDD是一個很大的話題,我這裏就不再贅述。但是有一點一定要記住:TDD is not about Testing。作爲結果的測試套件,只是一個副產品。更爲詳細的信息可以參考Kent Beck的《Test-Driven Development》和Robert Martin的《Agile Software Development》。另外,關於測試認識方面更爲詳細的信息,可以參考我去年在IBM developerWorks上發表的《軟件測試認識中的誤區》一文。

 

談到TDD,我不禁想起了前兩天和兩位朋友探討覆蓋率的必要性方面的問題。一位朋友最後舉出了一個例子,Kent Beck在《Test-Driven Development》一書中說TDD實施的結果必然是100%(或者接近)的測試覆蓋率。其實,在談論TDD時,一般是不會討論測試覆蓋率的,Beck先生這樣做只是爲了和傳統的理解有個可比性。爲什麼實施TDD後,會很容易地達到100%的覆蓋率呢?原因是這樣的:TDD使你關注於職責測試,在進行TDD時,你得不斷重構你的代碼使之符合好的原則,你得不斷消除代碼中的味道。最終的結果,你得到的是一個職責單一,沒有重複,接口正交、緊湊,方法短小且不含(或者很少)分支的類(模塊)。而你又是基於職責測試的,想不達到100%都難。是的,好的代碼必然會很容易地帶來足夠高的測試覆蓋率。

 

下面,我想談一下對於想在公司範圍內進行測試推廣方面的一些建議,僅供參考:

 

l         在測試用例文檔化方面,我持反對意見。我認爲測試用例代碼本身就是可以運行的文檔,而且永遠和實際的代碼保持同步,並且最爲直觀、清晰且沒有歧義。當然前提是我們必須要遵守TDD的紀律。如果真的需要書面化的文檔(這種情況很少會發生),我們可以通過self-documented的代碼來自動生成,比如在Java中可以使用JavaDoc工具。當然一些高層次的說明性文檔除外。

 

l         可以把覆蓋率作爲一個指標,但是不應該把它作爲唯一的指標。應該輔以其他更多緯度的度量標準。最重要的是要時刻關注高覆蓋的代價,如果代價很高,那肯定是代碼本身質量不高。

 

l         不應該以開發人員目前水平不高爲由,就只實施一些看起來“安全”的實踐。我們應該實施那些能夠提升開發人員技能,能夠使得他們變得更加優秀的實踐。在我們拒絕實施一些推薦實踐時,我們不應該只以“我們不希望你這樣做,因爲我們害怕你會偷懶”作爲判斷依據。

發佈了28 篇原創文章 · 獲贊 1 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章