2010年第9期的《程序員》雜志刊登了榮浩先生的文章《關于測試的八個問答》(在線版本發布在JavaEye上)。這是一篇充滿思辨的優質文章,有許多觀點值得借鑒。但是,我對如下文字有不同意見。
我說,那么,測試保證了質量?
神說,你覺得三鹿沒有測試嗎?
我說,....
神說,測試只是提供信息。至于這些信息的定義、重要性以及所要采取的反應都取決于人,而人做出的決定都是感性的,利益驅動的。
我嘆口氣,說,測試能夠保證軟件質量。
神說,如果開發的產品本身就質量低劣,進行測試你不覺得是浪費大家的時間嗎?一段時間發現的缺陷越多,并不意味著剩下的缺陷越少,而是意味著會出現更多的缺陷。
我說,我明白了,測試只是反饋信息,除此之外,并不能做其他任何事情。正如我們去體檢,體檢報告只能反映當時我們的身體狀態,至于健不健康,則取決于我們平時的生活習慣,這是兩個分開的事情,體檢并不保證我的健康。
神說,是的。
榮浩先生認為“測試只是反饋信息,除此之外,并不能做其他任何事情”。但是得出這一結論的推理過程是不嚴密的。
榮浩先生先用三鹿的例子精彩地指出一個事實:有些企業的負責人不顧質檢信息,出于私利,發布有重大缺陷的產品。在這樣的企業里,測試活動不能影響產品生產和發布,不能保證質量。之后,榮浩先生提出,如果產品質量非常低劣,測試可以發現大量的缺陷,但是“邊測邊改”的混亂過程無助于提高質量。
以上兩個觀點都是令人信服的。但是,它們是對兩個極端情況的分析,并不能得出普遍結論“測試只是反饋信息”。在大多數企業中,企業負責人不會草菅人命,他們被客服電話所折磨,也希望自己的產品能有個好質量。在大多數項目中,代碼質量即便達不到卓越,但也能夠滿足基本要求。在這樣的環境中,測試可以保證質量嗎?
我的觀點是:測試不能“保證”質量,但是測試有助于提高質量。
測試不能保證質量,是很容易理解的。按照現代質量理論,質量不是某個角色的職責,而是整個組織的職責;質量不取決于某項活動,它由所有活動共同構建。在軟件生命周期中,戰略規劃、需求協作、架構設計、編碼實現、測試檢驗、重構優化、推廣營銷,都對用戶可體驗的“質量”有重要影響。組織領導、項目經理、程序員、測試員都要對質量負責,他們的活動將共同決定產品質量。
雖然任何單一活動都不能保證質量,但是測試對于提高軟件質量有著重要作用。而且,其作用已經遠遠超越單純的“反饋軟件缺陷信息”。
對于開發人員,測試已經成為一項重要的設計與編程工具。
對于敏捷團隊,測試已經成為一項團隊支持工具。
對于測試者,測試負責且必須承擔反饋信息的職責,但是他可以做得更多。
任何嚴肅對待軟件的開發者都應該謹慎考慮Martin Fowler的話:
The reason JUnit is important, and deserves the Churchillian knock-off, is that the presence of this tiny tool has been essential to a fundamental shift for many programmers. A shift were testing has moved to a front and central part of programming.
JUnit 之所以重要且受到丘吉爾式的贊譽,是因為這個小工具對于許多程序員的根本性轉變至關重要。這個轉變是測試移動到編程的前沿和中心位置。(摘錄自《xUnit Test Patterns · 前言》)
以JUnit為代表的xUnit家族得以流行的根本原因是測試驅動開發(Test Driven Development)被普遍地認同和實施。Kent Beck將一種簡單的實踐發展為強大的編程工具,單元測試不僅是錯誤檢查者,還是類型設計工具、可執行的規格說明和重構安全網。Jimmy Nilsson將測試驅動開發提升到架構級別,利用具體的測試用例來實施領域驅動設計(Domain Driven Development)。測試不但是單元(類或函數)設計的驅動力,也是體系結構設計的驅動力。
任何設計都要落實到代碼且通過測試檢驗,才算完成。從抽象思考到代碼實現的過程就是“編寫測試,編寫代碼,通過測試、代碼重構”的反復循環。在每一個小循環中,測試、編碼、重構都對代碼質量作出密不可分的貢獻。單獨強調某一項活動的貢獻或忽略某一項活動的貢獻,都是不恰當的。
在敏捷團隊中,測試專家Lisa和Janet認為測試承擔兩種職責:支持團隊(Supporting Team)和挑戰產品(Critique Product)。從支持團隊的角度,測試可以視作一種開發活動。一些敏捷團隊使用用戶故事(User Story)來組織開發。在編寫產品代碼之前,程序員或測試員會和用戶協作,一起定義該故事的用戶驗收測試(User Acceptance Test)。他們通過編寫測試來實現“用戶協作”:挖掘需求,確定細節,建立共識。在故事開發過程中,持續集成會頻繁的運行各種測試用例集,來檢查最新的簽入(check-in)沒有破壞對產品的約定。對于任何故事,只有所有的單元測試、功能測試和用戶驗收測試全部通過,它的開發才算完結,才能被標記為完成(Done)。由此可見,測試至少在如下方面滲入到軟件開發的全過程。
與用戶協作編寫用戶驗收測試。它們作為可執行的規格說明,精確地描述了對產品的期望。
開發者編寫單元測試完以成單元設計,開發者編寫功能測試以完成代碼集成。
持續集成的測試通過率提供了開發狀態的重要信息。
用戶驗收測試的通過率提供了開發進度的重要信息。
測試仍舊是“反饋信息”。但是對于一個有進取心的團隊,它所提供的信息也是推動產品研發、監控開發流程、優化開發過程(優質的開發過程會緩慢但長遠地提高產品質量)的動力之一。
對于大多數測試者,測試的主體仍舊是“挑戰產品”并匯報在該過程中收集的信息。不過,測試專家們鼓勵我們用全新的視角考察測試。Chris McMahon在《測試之美》中提出了一個嶄新的、極富啟發性的隱喻:軟件是依賴于人的藝術品,測試者是“審稿人”。
Good software testers supply critical information about value to people who care about that value, in a role similar to that of a book reviewer or a movie critic.
原文轉自:http://www.anti-gravitydesign.com