每日一得

          不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速開發(fā)
          最近關(guān)心的內(nèi)容:SSH,seam,flex,敏捷,TDD
          本站的官方站點是:顛覆軟件

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
          key words: 真正的測試先行開發(fā) 測試驅(qū)動 Fitnesse


          摘要
          本文描述了如何使用開源的FitNesse來實現(xiàn)真正的測試先行開發(fā)過程,并讓客戶、需求提報工程師、開發(fā)人員、以及測試人員進行協(xié)同工作,達到需求更精準(zhǔn)、減少需求更改、測試數(shù)據(jù)與Junit單元測試代碼分離的目的,讓這一切更簡潔、更易于維護。
          作者:Stephan Wiesner
          譯者:陳海青(joson)

          在過去的幾年里,我在開發(fā)測試工作中擔(dān)任過各種角色,使用過服務(wù)器端的JavaScript,Perl,PHP,Struts,Swing以及模型驅(qū)動架構(gòu)等各類技術(shù)。盡管項目不同,但是他們有一些共同點:項目結(jié)束的時間越晚,就越難以達到客戶的真正需求。
          每個項目都有一些需求,有的非常詳細,有的卻只有幾頁紙,這些需求一般要經(jīng)歷以下三個階段:
          ---由客戶或者承包人來書寫或采納一些官方的驗收標(biāo)準(zhǔn)
          ---測試者試圖根據(jù)需求來找出軟件中不符合要求的地方
          ---項目開發(fā)完畢進入驗收測試, 可是客戶突然又提出對軟件需求進行補充或變更的要求

          最后一個階段將導(dǎo)致項目發(fā)生變化,開發(fā)期甚至要超出最后期限,使開發(fā)人員的工作壓力劇增,從而導(dǎo)致發(fā)生更多的錯誤。Bug的數(shù)量將快速增長,系統(tǒng)的質(zhì)量將下降。聽上去是不是很熟悉?

          現(xiàn) 在讓我們看一下在上述的項目開發(fā)中發(fā)生了哪些錯誤:客戶、開發(fā)、測試人員沒能協(xié)同工作;需求已經(jīng)確認通過,但是在不同位置的人可能還用不同的需要未考慮。 另外,開發(fā)者一般會寫一些自動測試代碼,測試人員也試圖進行自動化測試,但是他們往往不能充分協(xié)同,許多項目被重復(fù)測試,但另一些(經(jīng)常是更困難的部分) 卻沒能被測試,客戶也沒參與到測試工作中。本文所介紹的就是通過自動測試與項目需求相結(jié)合的方式來解決這些問題的一種方案。

          版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時請務(wù)必保留以下作者信息和鏈接
          作者:Stephan Wiesner ;joson(作者的blog:http://blog.matrix.org.cn/page/joson)
          原文:http://www.javaworld.com/javaworld/jw-02-2006/jw-0220-fitnesse.html
          Matrix:http://www.matrix.org.cn/resource/article/44/44507_FitNesse.html
          關(guān)鍵字:FitNesse;Test

          開始FitNesse

          FitNesse 是一個增加了可觸發(fā)Junit 測試等附加功能的wiki程序。如果這些測試能夠與業(yè)務(wù)需求結(jié)合起來,就會使業(yè)務(wù)需求更加清晰。而且,測試數(shù)據(jù)的組織更有邏輯性。使用FitNesse更 重要的是學(xué)習(xí)隱含在其中的一些思想,某些部分需求可以作為測試的一部分,這意味著,這些需求是可以測試的,或者說是可以進行校驗的。

          利用 FitNesse,開發(fā)的工作過程可以這樣描述:需求工程師使用FitNesse書寫業(yè)務(wù)需求(取代了一般文檔)。他試圖盡可能讓客戶參與其中,當(dāng)然這并 不是每天都能做到的。而測試者在反復(fù)研究這些文檔,并從第一天起就開始提問各種問題,因為他們考慮問題的方式不同,不是在考慮“軟件應(yīng)該實現(xiàn)些什么”?而 是在考慮“怎樣才能讓軟件出錯?如何讓軟件中斷運行?”等。開發(fā)者更象一個需求工程師,他更想知道“軟件必須要完成它的功能是什么”?

          測試人員可以更早地開始測試,甚至在需求沒有全部完成前,而且可以把測試寫進業(yè)務(wù)需求中,這些測試不僅僅成為需求的一部分,而且也將成為需求評審和驗收的重要過程,并具有以下幾方面的重要優(yōu)點:

          ---客戶也會被吸引來開始考慮關(guān)于測試的事情,通常他們還會參與到建立測試的工作中來(你也許會吃驚,他們怎么對這些這么感興趣了。)
          ---相關(guān)規(guī)范將更詳細、更周密,因為測試總比單純的文字要準(zhǔn)確.
          ---通過這種方式,可以更清晰明確地了解軟件(象一個軟件原形,但是功能更多),因此可以更早地考慮真實的運行場景,提供測試數(shù)據(jù)和測算結(jié)果。

          最后,需求將提交給開發(fā)人員,他的工作要比以前要更容易些,因為需求都附帶具體的實例,因而更貼近實際需求,因此減少了被突然改變的機會。下面,就讓我們看一下這個過程是如何使開發(fā)者工作更輕松的吧。

          測試先行的實現(xiàn)

          通 常情況下,測試先行開發(fā)中最困難的是沒人愿意花費那么多的時間來寫測試,而更愿意去考慮如何讓軟件工作起來。按照上述的過程,開發(fā)者把功能測試看作合同的 一部分,他的任務(wù)要從“按要求編程,檢測并修改”轉(zhuǎn)變?yōu)椤白寽y試運行起來”。現(xiàn)在,在確定應(yīng)該做什么,何時完成,項目的定位等方面,我們有了更好的方法。

          并非所有的測試都可以自動進行,并非所有的部分都可進行單元測試。我們通常將測試劃分為以下幾種類別:
          ---數(shù)據(jù)驅(qū)動的測試,需要通過單元測試來完成,如計算就是一種典型的例子.
          ---關(guān)鍵字驅(qū)動 (Keyword-driven) 測試,常自動化進行。這是一些系統(tǒng)測試,要求應(yīng)用程序能夠運行,按鈕能夠被點擊,數(shù)據(jù)可以被鍵入,而輸出的結(jié)果中包含規(guī)定的值。測試團隊一般都能實現(xiàn)這種測試,但是可能開發(fā)者更容易完成這些工作。
          ---手工測試。這類測試適用于或者實現(xiàn)自動化測試的代價太昂貴并且是對出錯的要求不高的情況,或者是一些基礎(chǔ)功能(如,起始頁面不能顯示),可以很容易地發(fā)現(xiàn)錯誤的情況。

          我是在2004年首次接觸FitNesse,我曾經(jīng)嘲笑過它并揚言它是不可能工作的。把測試寫入wiki并自動進行測試,這個主意看起來太荒唐。但是,我錯了,F(xiàn)itNesse真的象看起來得那樣簡單高效。

          FitNesse的簡單是從安裝時就開始體現(xiàn)了,只要完全下載了FitNesse的發(fā)行包,并解壓縮就可以了。在以下的討論中假設(shè)解壓到了c:\fitnesse目錄中。

          運 行C:\fitnesse 下的run.bat(linux 下運行run.sh)來啟動FitNesse,F(xiàn)itNesse作為一個web服務(wù)運行在80端口上,當(dāng)然你可以指定端口,如設(shè)定81,在運行腳本的首行 加上 –p 81 即可,這就是設(shè)置的全部工作。現(xiàn)在你可以用http://locahost:81來訪問你的FitNesse了。

          在本文,我使用windows平臺的java版FitNesse,當(dāng)然,這些例子也可以用于其它版本和其它平臺(如Python,.net等)

          一些測試

          你 可以從FitNesse的在線文檔提供了一些例子(可以與有名的Junit的貨幣用例相提并論)開始做起,這些例子非常適合學(xué)習(xí)如何使用 FitNesse,但是它們還不算是解決復(fù)雜問題的例子。因此,我將使用一些在我最近項目中的真實的用例。我已經(jīng)簡化了問題、代碼,而不是直接取自項目 中,并寫了一些說明。盡管如此,這些例子還是足夠復(fù)雜,能夠充分展示FitNesse簡潔直觀的威力
          現(xiàn)在,假設(shè)我們正在從事一個為一個大型的保險公司開發(fā)開發(fā)項目,這是一個復(fù)雜的基于java的企業(yè)級應(yīng)用。產(chǎn)品將涵蓋公司的全部業(yè)務(wù),包括客戶和合同管理,以及支付業(yè)務(wù),在我們的例子里,我們只關(guān)注其中的極小的一部分。

          在瑞士,父母有權(quán)利獲得給每個孩子的兒童津貼,經(jīng)過確認家庭環(huán)境后,將根據(jù)情況得到相應(yīng)的津貼。以下是這個需求的簡化版本,我們將從一個傳統(tǒng)的需求開始,并把它遷移到FitNesse中。

          兒童津貼的發(fā)放存在幾種狀態(tài)。有關(guān)條款規(guī)定在孩子出生月份的第一天開始生效,在孩子達到規(guī)定年齡、就業(yè)或死亡的所在月份的最后一天失效。

          按規(guī)定在到了12歲所在月份的第一天,就可以領(lǐng)到190瑞士法郎(瑞士官方貨幣)的補貼。
          根據(jù)父母全職或兼職工作等情況,依據(jù)不同的條款,如表1所示進行分類.

          image
          圖 1. 兒童津貼資格表.

          就業(yè)率要根據(jù)工作合同來計算,合同需要被確認是有效的,如果有終止日期,還要確認是否在“有效期”內(nèi)。表2顯示了根據(jù)孩子年齡的不同等條件,父母可以得到的補貼數(shù)量。

          image
          圖 2. 年齡相關(guān)條款

          正常情況下,每兩年要對款項進行有規(guī)律地調(diào)整。

          第一次看到這些需求,也許會認為這些需求是很明確的,開發(fā)人員有能力輕松地實現(xiàn)它,但是,我們真的確定了這些邊界條件了嗎?該如何測試呢?

          邊界條件
          邊界條件是指達到、超過、低于某個給定的輸入輸出之的情況。經(jīng)驗表明,在邊界條件附近的測試比其他測試更有價值,典型的例子就是著名的“只執(zhí)行一次”的條件跳轉(zhuǎn)和程序段.


          場景對于查找例外條件和邊界條件有很大幫助,因為這是得到關(guān)于商業(yè)規(guī)則的行業(yè)經(jīng)驗的好方法。

          場景

          對 大部分項目而言,是由需求工程師來提供給開發(fā)人員的需求規(guī)格說明書,然后開始學(xué)習(xí)了解需求,提問,然后開始設(shè)計、編碼、測試。再后來,開發(fā)人員把軟件提供 給測試團隊,在經(jīng)過幾番改寫和修補后,最后交付給客戶(客戶也許更喜歡考慮提出一些意外的需求)。如果采用了FitNesse,將不會改變這一過程,只是 要增加一些測試用例、場景,和測試意愿。

          場景在啟動測試過程中具有特別的的幫助。以下是一些例子,在回答將支付多少兒童津貼等為題上,就要分清多種情況:
          ---瑪麗亞是單親家庭,她又兩個兒子 (鮑勃, 2歲,??彼得 15歲) ,從事兼職秘書工作 (每周工作20個小時).
          ---瑪麗亞失業(yè)了,后來她找到一個每周工作10個小時的商店助手和每周工作5個小時的臨時照顧幼兒的工作
          ---保羅和拉瑞(Lara)有一個17歲的女兒麗莎(Lisa),她是一個殘疾人,還有一個兒子弗蘭克,18歲,還在上大學(xué)。
          即使是僅談?wù)撘幌逻@些場景,也有助于測試工作的開展,哪怕是軟件中手工運行這些例子,也幾乎可以確信會發(fā)現(xiàn)程序的遺漏,難道因為沒有原型就不做這些嗎?為什么不做呢?

          關(guān)鍵字驅(qū)動(Keyword-driven)的測試

          關(guān) 鍵字驅(qū)動的測試常用于模擬原型,F(xiàn)irNesse允許定義關(guān)鍵字驅(qū)動的測試類型(詳見“完全的數(shù)據(jù)驅(qū)動自動化測試”(“Totally Data-Driven Automated Testing”))甚至在沒有軟件支持的情況下(不能自動運行),運行基于關(guān)鍵字驅(qū)動的測試也會很有好處。

          image
          圖 3. ActionFixture 測試

          圖3 展示的是關(guān)鍵自驅(qū)動測試的示例。第一列描述的是來自FitNesse的關(guān)鍵字,第二列描述的是java類的方法(開發(fā)者根據(jù)這里的描述,在Java程序使 用這些名字來命名)。第三列描述的是來自第二列的方法所產(chǎn)生的數(shù)據(jù)。最后一行演示了測試失敗的情形(測試通過為綠色)。正如你所看見的那樣,找出錯誤是很 容易的。

          這會使人很容易甚至很樂意去建立這些測試。測試者不必具備編程技能,經(jīng)過簡短介紹后,客戶也會很容易的讀懂。
          用這種方法定義的測試,幾乎就是業(yè)務(wù)需求,并具備傳統(tǒng)測試用例沒有的重要優(yōu)勢, 甚至不必去自動生成也有很多優(yōu)勢:
          ---測試內(nèi)容很容易獲得,不必特別訓(xùn)練就可以輕松完成。
          ---與其改變需求,到不如先改變測試,這樣反而更直觀(這與使用某些工具的情況完全不同)
          ---在確定新需求或修改需求時,可以隨時運行測試來看看需要修正哪些內(nèi)容。

          為自動運行測試,需要建立一個簡單的軟件層,用于代表真實的測試代碼。這些測試在自動化測試GUI操作時特別有用。我曾開發(fā)過一個基于HTTPUnit的自動測試web頁

          這里就是FitNesse自動運行的代碼:
          package stephanwiesner.javaworld;

          import fit.ColumnFixture;

          public class ChildAllowanceFixture extends ColumnFixture
          {
          ?? public void personButton() {
          ??????System.out.println("pressing person button");
          ?? }
          ?? public void securityNumber(int number) {
          ??????System.out.println("entering securityNumber " + number);
          ?? }
          ?? public int childAllowance() {
          ??????System.out.println("calculating child allowance");
          ??????return 190;??
          ?? }
          ?? [...]
          ??}


          在FitNesse中的運行結(jié)果如圖4所示,很有助于調(diào)試。與Junit相比,Junit抑制了調(diào)試信息的輸出,但我認為在自動Web測試中這些輸出絕對是有必要的。

          image
          圖 4. 標(biāo)準(zhǔn)輸出

          在測試基于Web的應(yīng)用時,錯誤也將被包含在FitNesse頁面里,并被顯示出來,這是的條施工作比使用log文件更容易。

          數(shù)據(jù)驅(qū)動的測試

          關(guān) 鍵字驅(qū)動的測試是GUI自動測試的最佳選擇,同樣,數(shù)據(jù)驅(qū)動測試也是各類計算類項的首選測試方式。如果你曾經(jīng)寫過單元測試,那么測試中什么是最令人厭倦的 呢?也許,你會認為是數(shù)據(jù)。你的測試要進行數(shù)據(jù)填充,但是數(shù)據(jù)經(jīng)常改變,使維護工作變成了可怕的惡夢,測試不同的組合,需要不同的數(shù)據(jù),這也許會使你的測 試工作變得日益復(fù)雜,變成了”丑陋的怪獸”。

          使用數(shù)據(jù)驅(qū)動的測試,數(shù)據(jù)將從代碼中分離。一般情況下,建立幾種類型的表格,存儲為CSV文件,由測試代碼來讀取。如果再使用FitNesse,我們就可以更便利地進行存儲、改變,以及訪問這些測試數(shù)據(jù)。

          現(xiàn) 在,讓我們把圖2種的表格轉(zhuǎn)變成一個測試吧。首先,將表格拷貝到Excel中,進行修改,然后使用FitNesse的EXCEL導(dǎo)入功能輸入。這是一個有 用的功能,因為在FitNesse中,表越大越難以維護。輸入的結(jié)果如圖5所示。每一行表示一個測試,有問號的列表示需要寫Java方法,沒有問號的行表 示輸入的測試數(shù)據(jù)。

          image
          圖 5. 數(shù)據(jù)驅(qū)動測試表Data-driven test table.

          再 重復(fù)一次,在閱讀了業(yè)務(wù)需求后,這種測試就非常容易理解了。如果你曾經(jīng)擔(dān)心如何在你的測試用例里的進行等值測試的話,那就看看這里吧。最后一行大概是最重 要的,因為需求并沒有說明如何處理非法數(shù)據(jù),或者處理20歲以上的孩子但仍在上學(xué)等情況,這里的關(guān)鍵字“error”表明需要處理異常了。

          常見問題解答

          這里討論使用FitNesse在需求、測試和開發(fā)過程中遇到的未解決的問題的解決辦法,以下是部分答案。

          手工測試會遇到什么問題?
          手 工測試者最常做的就是重復(fù)的手工回歸測試,不但代價昂貴,而且容易出錯。自動化測試可以減少但不能消除這種工作的工作量。測試者可以有更多的時間去從事更 有趣的測試,例如在應(yīng)用程序在復(fù)雜的場景下的不同處理等,盡管測試就是要花費更長的時間找到錯誤,但比不意味著因此而要付出更高的代價.

          用戶驗收測試不再有必要了嗎?
          也許有人會這樣認為。如果客戶在需求中定義了所有的測試,當(dāng)所有測試測試都變綠(通過了)時,軟件就“完工”了。我的實踐經(jīng)驗是,客戶仍會提出附加的需求來,盡管如此,他們的需求變化會更少,并更容易地結(jié)合實際變化進行分類(同時也會帶來追加的款項)。

          在FitNesse書寫比Word documents更有優(yōu)勢嗎?
          甚至在沒用測試的情況下,使用wiki 來寫業(yè)務(wù)需求也能帶給你更多好處。文檔可以自動用在Web 服務(wù)器上,可以被多人并發(fā)訪問,可以全文檢索,可以被鏈接。我發(fā)現(xiàn)還有以下兩個特點:
          ---更容易建立數(shù)據(jù)字典,并鏈接上明細內(nèi)容。更重要的是,具有查找被引用位置("where-used")的功能。 如果修改某個細目,就會立即找到是否被引用過,以避免發(fā)生沖突.
          ---由于Bugzilla (或者 Jira,二者均為缺陷跟蹤系統(tǒng),譯者注) 是基于Web的, 我們可以方便地在兩個系統(tǒng)之間互相鏈接文檔(artifacts) (bugs, 任務(wù), 討論等),便于提高工作效率。

          FitNesse 允許按照確定的順序運行測試,而JUnit 禁止這樣做,你有何體驗?
          使 用JUnit,需要對同一個對象分別建立許多setUp() 和tearDown() 方法. 在某些情況下,可以在一個FitNesse頁面里放上所有的相關(guān)測試,并能夠給定執(zhí)行順序. 因此,第一個測試可以建立一個”人”,下一個測試可以對它進行修改,最后一個可以進行刪除操作.如果第一個測試失敗了,而且那個”人”沒有被建立,這該怎 么辦?沒問題,因為第一個測試失敗了,隨意在把它修正好之前,我是不會繼續(xù)的. 我一般不會經(jīng)常使用這種順序執(zhí)行方式,但有時它會給我?guī)砗艽蠓奖?

          FitNesse 可以用于大項目嗎?
          大 部分開發(fā)者會明白,F(xiàn)itNesse的優(yōu)勢就是簡單易用。但沒有技術(shù)背景的人,如果不使用自動檢查特性以及所見即所得風(fēng)格的編輯器,工作起來會很困難。一 個簡單的例子就是FitNesse 只有允許使用三種類型的標(biāo)題, 但現(xiàn)在我們需要五種,這就需要我們就可以對FitNesse 進行擴充.

          FitNesse 不包含輸出為類似PDF文件的功能。我曾經(jīng)使用過長度達到60頁的Word文檔,盡管編輯起來有些困難,但是可以輕松打印出來. 但是當(dāng)我把它轉(zhuǎn)到FitNesse里后,我就難以打印了,因為被分解為幾個不同的頁面,最后不得不通過編程解決.

          FitNesse 具有一個簡單的機制可以顯示那些文檔被修改了,被誰修改了,但不能顯示修改了什么, 權(quán)限管理有局限。使用FitNesse重開一個項目要比改寫一個運行的項目更容易.對中小型項目而言,我極力推薦FitNesse. 大項目也可以使用,但是進行更仔細的評估后再實施會更好.

          結(jié)論
          我認為FitNesse是需求分析的好工具,對測試優(yōu)先開發(fā)很有幫助,它是很有利用價值的。我被迫花費幾個周來適應(yīng)FitNesse及其處理過程,我的項目目前尚未完成,但是我已經(jīng)看到了需求質(zhì)量和軟件質(zhì)量均得到明顯提高,而對測試者而言,工作起來會獲得更多的樂趣 。

          關(guān)于作者
          Stephan Wiesner 是瑞士盧賽恩Löwenfels Partner AG的測試管理人員。他是“Learning Jakarta Struts 1.2”(伽利略出版社,德語版,ISBN:3898426130;英語版:ISBN: 190481154X)的作者,” Java der Code”(由德國MITP出版社發(fā)行,ISBN: 3826614623)。另外還在德文雜志上寫過大量的與java相關(guān)的文章。他有著豐富的開發(fā)和測試經(jīng)驗,是一位ISTQB認證的測試管理員和認證的 Scrum主管(ScrumMaster,Scrum是一種敏捷開發(fā)方式,譯者注)。

          陳海青(joson),本文譯者,生活在中國的山東省煙臺市,先后從事軟件開發(fā)、數(shù)據(jù)庫管理、系統(tǒng)管理等工作,2001年獲得高級程序員資格。

          相關(guān)資源
          ---Matrix-Java和中間件社區(qū):http://www.matrix.org.cn
          ---“完全的數(shù)據(jù)驅(qū)動自動測試”("Totally Data-Driven Automated Testing" ),作者Keith Zambelich ,詳細闡述了數(shù)據(jù)驅(qū)動和關(guān)鍵字驅(qū)動的測試: http://www.sqa-test.com/w_paper1.html
          ---以下站點提供了更多的關(guān)于優(yōu)化FitNesse的內(nèi)容: http://fitnesse.testmanager.info
          ---官方的FitNesse網(wǎng)站,經(jīng)常更新: http://fitnesse.org/
          ---下在完整的FitNesse發(fā)行版: http://fitnesse.org/FitNesse.DownLoad
          ---部分資料可以在譯者的站點找到:http://www.chq.name/

          作者的其他文章

          其他相關(guān)文章

          posted on 2006-07-28 11:43 Alex 閱讀(2973) 評論(0)  編輯  收藏 所屬分類: XP-極限編程

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 陇南市| 准格尔旗| 凭祥市| 山西省| 扶风县| 垦利县| 石河子市| 壤塘县| 杭锦后旗| 城固县| 安吉县| 潞城市| 无极县| 鸡西市| 奉贤区| 赤城县| 临沧市| 长沙县| 华安县| 双峰县| 湟中县| 百色市| 台山市| 闵行区| 长治市| 利川市| 翁牛特旗| 兴业县| 卫辉市| 潞城市| 余庆县| 涟水县| 曲松县| 新龙县| 留坝县| 达日县| 双江| 荥阳市| 米脂县| 金塔县| 锦州市|