測試驅動的開發——概述

發表于:2008-02-03來源:作者:點擊數: 標簽:測試驅動
Test_Driven Development Series Part I:Overview By Wellie Chao 出處 http://www.theserverside.com/resources/article.jsp?l=TestDrivenDevelopmentPart1 December 2003 一、簡介(Introduction) 你可能已經聽說了這個新名詞:測試驅動的 開發 (test-driven
Test_Driven Development Series Part I:Overview

  By Wellie Chao

  出處 http://www.theserverside.com/resources/article.jsp?l=TestDrivenDevelopmentPart1

  December 2003

  一、簡介(Introduction)

  你可能已經聽說了這個新名詞:測試驅動的開發(test-driven development),它在廣大程序員、各種雜志網絡中程序員常去的地方都非常流行。它究竟是什么呢?測試驅動的開發是一種方法理論,它強調把測試作為開發過程的一個主要部分。要是關心程序質量的話,在部署之前前就應該測試。幾乎所有人都使用某種方法進行測試,所以你可能會問:測試不已經是開發過程的一個部分了嗎?測試驅動的開發要讓測試成為開發過程的主要部分。

  二、手工測試(Manual Testing)

  早期的軟件開發時,許多人的測試方法就是運行程序,通過手工操作來指定輸入然后觀察輸出?,F在還有很多軟件的開發繼續著這種方式。它有一個關鍵的優點:非常容易學習和理解。如果你有鍵盤和鼠標,并且會操作圖形界面,你就可以測試任何桌面應用。如果你有web瀏覽器,你還可以測試web應用。這根本談不上什么技巧,你可以認為所有開發人員都能做到。手工操作時你看到的應用和最終用戶看到的完全相同,這也是一個不錯的主意,但并不是真正的優點,因為其它的測試方法也能做到。

  手工測試的缺點就實在太多了:

  手工測試需要反復進行。每一次修改程序,不管是增加新特征,改變已有行為,還是修改bug,你都必須重新測試被影響的部分,才能保證你增刪改的代碼不會造成破壞。

  手工測試可能帶來錯誤。人類不適合作重復性的工作,特別是這個工作還很煩人的話。人類經常忽略細節,這會導致代碼被破壞。更可能造成的問題是:修改這個地方,可能會影響到另一些代碼的行為,盡管它們的關系不是很明顯。因此,即使你作了非常認真負責的測試,那也只限于你認為修改可能影響到的部分,你還是有可能會在其它地方漏掉一些bug或被破壞的功能,不是因為你不夠仔細,而是因為軟件開發是綜合性的工作,軟件的各個部分常常有關聯,在現在的軟件項目中,任何人都不可能詳細了解某段代碼所有的依賴和被依賴關系。

  手工測試無法對不可視組件進行單獨測試。如果你只測你能看到的,那你就沒測你看不到的。這看上去是非常簡單的一個命題,但它的意義重大。軟件是復雜的,為了定位和解決錯誤或被破壞的代碼,大量形態各異的bug需要通過“剝繭抽絲”式的測試去分析每一個組件的行為。對于服務器端軟件尤為如此。服務器端程序中,幾乎所有的重要代碼都在邏輯層,如基于web的程序。表示層測試只能間接的測試業務邏輯,可能忽略某些細節。你當然希望邏輯層和表示層都能很好的工作,但邏輯層正常工作是整個應用能正常運行的基礎。

  如果你的測試是手工進行的,別人就沒法判斷你的程序功能是否正確。其他人(例如其他開發人員或者甚至是最終用戶)只能接受你的承諾:你作了測試,各方面都滿足需求。除了你的書面或口頭聲明保證你對程序作過測試它滿足所有可視的檢查外,其他人沒辦法驗證功能正確,除非他們自己辛苦的作一遍測試,但這個工作可能并不適合他們,因為他們不熟悉程序的邊界條件和邏輯。

  三、自動測試(Automated Testing)

  自動測試解決了手工測試的不足。因此,要回答“除了軟件開發中一直在做的那些事情外,測試驅動的開發到底意味著什么?”這個問題,測試驅動的開發在整個開發過程中引入自動測試,并不斷改進這些測試以適應程序代碼的擴展。注意這中間的兩個要點,第一,測試是自動的表示它不但可以重復進行,還要很方便移植,可重復是指你可以一遍又一遍的對同樣的代碼進行測試,并且每次都得到同樣的結果;方便移植是指別人可以使用你的測試,自己來驗證你的程序是否能通過這些測試。第二點要求測試的改進包含到程序本身代碼的改進中,測試落后于代碼可不是件好事,因為這樣測試就不能真正的驗證程序功能正確與否,因此測試代碼需要與應用本身的代碼保持同步前進。

  軟件的自動測試有兩個主要方法。第一個是通過可重現的recorded macros。Mercury Interactive (http://www.mercuryinteractive.com/products/winrunner/)的WinRunner等就是用的這種方法。盡管很容易建立,但宏是很不穩定的,需要經常修改,因為它們通常依賴于按鈕和組件的物理位置,而不是在parsed document中的結構位置。對開發人員來說,測試框架不管是產生不正確的錯誤信息,還是需要大量的工作才能保持和代碼同步,都是非常痛苦的事情,

  第二個進行web應用自動測試的主要方法就是通過編程API。這樣你就有了測試框架,軟件庫可以檢查條件是否滿足,報告錯誤的數量和類型,你可以在測試代碼中調用這個框架。你的測試代碼就是繼承自測試框架的一套標準Java類,它們從應用代碼中初始化對象,調用方法來驗證給定輸入會得到預期的結果。采用編程API方案的包括JUnit、HttpUnit、各種單元測試和黑盒web測試的工具等等。這種方案非常靈活,大多數情況下它大大減少了測試代碼的維護時間,并且使應用中的復雜功能測試成為可能,尤其是服務器端應用。這種測試可交替的調用programmatic testing,API-driven testing,或者programmatic API-driven testing。

  相對于recorded macros模式來說,基于API的自動測試方法的第一個弱點是它的需要更長創建時間。當你的問題是鼠標移動和點擊時很難減少設置時間。第二個問題是絕大多數客戶不會寫測試程序的??蛻袅私獾氖菢I務過程,而不是技術,客戶可能覺得移動鼠標和點擊鼠標容易得多,這一點非常重要,如果你想讓客戶在開發過程中就參與進來的話,客戶參與是極限編程的鼓吹者推薦的方法。

  雖然如此,基于API的方法在許多方面存在著優越性,可以在大多數應用中使用,因為應用程序隨時間改變的程序非常大,所以花在測試程序維護上的時間比測試程序的創建時間占的比例更大。而且recorded macro方法有一個致命限制:只有在應用代碼寫完之后你才能建立測試。如果你們的開發習慣是不在程序完成前測試,那非常好。否則,如果你堅持測試先行的習慣,正如作者推薦的,那非常不幸recorded macros不適合你,因為在記錄宏進行重放之前,你必須有一個能運行的應用程序。

  好的方案可能既有recorded macros測試,又有基于API的程序化測試。通過鼠標拖點式測試你可以讓最終用戶參與到測試中來,保證你的程序滿足業務需求。通過程序化測試則可以在技術角度確保程序組件按預計的情況工作。

  使用程序化測試,你有兩種選擇:功能測試和單元測試。功能測試也叫做黑盒測試,是指在不知道(或者忽略)內部實現的情況下,在一個較高的層次上進行測試。功能測試用于驗證程序是否完成業務需求,它模擬采用與最終用戶一致的方式與程序進行交互。最終用戶可能是使用基于web應用的業務人員,也可能是通過你所提供的API來使用你的類庫的開發人員。如果你一定要糾纏概念,功能測試和黑盒測試還是有一些區別的,因為技術上功能測試可以在容器內進行(如果要測得是web程序的話),但實際上絕大多數功能測試是在黑盒中做,除了公布的接口外你一無所知。相反,單元測試包括底層代碼的驗證,為了對確保內部組件沒有問題,必須了解程序的內部結構。你還需要知道那些類和方法的實現。如果要測的程序是給開發人員使用的軟件庫,你的單元測試包括所有重要的類和方法,甚至在發布給用戶的API文檔中沒有列出的內容。功能測試與程序交互的方式是通過點擊按鈕和信息入口,進入程序可見的forms。單元測試與程序的交互是通過Java方法調用來訪問。

  對前面提到的手工測試的四個缺陷,自動測試都給出了很好的解決:

  排除重復。用自動測試你可以把這項工作交給計算機去辦,它們將嚴格按照你每次測試的流程進行操作。

  減少錯誤。計算機每次都用同樣的方式執行重復操作。而且,因為測試是cumulative,而且容易調用,即使某一些代碼修改在直接影響范圍之外很遠的地方造成破壞,你仍然能找到這個錯誤,因為你以前寫的檢查那些(被破壞的部分)代碼的測試會告訴你。自動測試的cumulative是一個非常有用的特點,也是相對手工測試來說一個重要的優點。用手工測試來檢查程序的其它部分是不切實際的。

  允許組件的獨立測試。自動測試,至少其中的基于API的程序化方式,可以讓你測試程序的不可視部分,例如你認為是程序核心的業務邏輯。編程測試在其它程序(測試代碼)中調用你的代碼。粒度由你自己把握。如果不考慮程序的任何內部實現,你可以模擬一個web瀏覽器或者使用鼠標操作桌面的用戶,進行黑盒或功能測試。你也可以調用類庫德公共API,因為你不考慮API內部的實現,這也可以算作一種黑盒或功能測試。你還可以調用隱藏類或公共類的內部方法,來驗證它們按你想的方式工作,因為針對的是獨立的方法和類,而且你會知道算法等內部實現細節,這就是單元測試。你要做什么測試,就選擇什么級別的細節。

  讓最終用戶自己來驗證軟件的功能正確。它的作用不僅在于防止破壞用戶數據的bug,而且可以幫助發現你的軟件在新的環境中可能出現的無法預料的問題。新的環境包括不同的操作系統,新的硬件平臺,不同的網絡配置,或者各種各樣的其它差異。自動測試可以把你的測試轉移到其它平臺上,確保你的程序在任何地方都能正確運行。

  四、工具(Tools)

  下面的幾個工具對自動測試非常有用:

  JUnit。JUnit是單元測試的鼻祖。其它工具經常在JUnit基礎上創建,因為JUnit提供了單元測試和功能測試都必須用到的兩項功能:斷言檢查和結果報告??梢栽趙ww.junit.org找到JUnit.

  HttpUnit。HttpUnit是在JUnit之上構建的測試框架,它支持web應用的黑盒測試和in-container測試。它是功能測試工具,你可以用它驗證軟件符合業務需求,在可視的級別符合預期行為。有趣的是,HttpUnit的基礎代碼實際上跟測試沒什么關系。HttpUnit庫的目的是加強HTTP對web應用的訪問,它支持的特征包括狀態管理(cookies)、請求提交、應答解析(HTML解析),以及網絡蜘蛛(web spider)工具包需要的一些特征。HttpUnit還有一個支持容器內測試的類ServletUnit。在JUnit提供的斷言功能和結果報告功能的基礎上,HttpUnit成為了一個測試web應用非常有用的工具??梢栽趙ww.httpunit.org找到HttpUnit,

  jWebUnit. jWebUnit是在HttpUnit上創建的一個輔助工具包,它減少測試web程序需要你寫的代碼。簡單的說,你可以把它當作HttpUnit的宏程序庫,提供到HttpUnit代碼段的快捷方式,簡化web程序測試中的大多數行為。HttpUnit提供相對底層的接口讓你自己定制許多事情。你可能覺得jWebUnit有用,也可能不,如果用HttpUnit可以解決你的所有問題,jWebUnit也可以。它可能帶來更多的代碼,但你有更好的控制??梢栽趆ttp://jwebunit.sourceforge.net/找到jWebUnit。

  StrutsTestCase. StrutsTestCase是為測試Struts應用在JUnit基礎上創建的測試框架。Struts是用Java開發web應用的程序員非常喜歡的模型-試圖-控制器(MVC)平臺,它簡化了數據、表示和邏輯分離的易維護性組件式代碼開發。Struts使web程序容器間(in-container)的功能測試和單元測試變得復雜,因為它們夾在servlet容器和你的程序之間。這就意味著這個測試框架要認識Struts,能處理Struts的容器間測試。由于不需要知道web程序的內部實現,HttpUnit的黑盒測試仍然工作得很好。然而你無法用HttpUnit做Struts應用的容器間測試,因為HttpUnit要獨立的位于你的程序和servlet容器之間。StrutsTestCase是專為Struts程序的的容器間測試設計的。StrutsTestCase可以在http://strutstestcase.sourceforge.net/獲得。

  五、總結(Conclusion)

  如果你同意測試是重要的,而不僅僅是需要的,那么你就會開始自動化你的測試,或者繼續已經使用的自動測試。如果你同意自動測試比手工測試優越,那么在開發程序代碼的同時發展自動測試就是合理的。維護測試代碼只是增加了一點點負擔,但它使你不必擔心程序是否滿足測試代碼的需求。采用了自動測試和程序代碼修改的同時維護測試代碼這兩個原則,你就是采用了測試驅動的開發。程序的可靠性和質量都會得到提高,你的客戶,不管是外面的零售客戶,還是其他部門的同事,可能會感謝你,也可能更少的因為軟件不穩定打擾你,或者兩都都有。最后,寫測試代碼比反復的用鼠標點來點去的測試軟件有趣得多。

  現在準備閱讀測試驅動的開發系列的下一篇論文。這篇標題為“業務層測試驅動的開發”(“Test-driven Development for the Business Tier”)的論文將探討服務器端組件測試的細節,包括EJB和普通的Java類。

  作者

  Wellie Chao從1984年開始對軟件開發產生興趣,并在1994年成為職業程序員至今。他領導了幾個構建企業應用的軟件項目,在Java和Perl語言上有很深的造詣,他出版過幾本Java的書籍,其中“Core Java Tools”(Prentice Hall)講述了用Ant、CVS和JUnit等開源Java工具進行極限編程和測試驅動的開發等主題。他在IBMdeveloperWorks、DevX、TheServerSide和其它地方發表的論文涵蓋了開發企業軟件的Java程序員感興趣的主題。他榮幸的畢業于哈佛大學,在那兒他攻讀經濟學和計算機,他現在住在紐約。

原文轉自:http://www.anti-gravitydesign.com

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