軟件測試的新模型

發表于:2007-04-22來源:作者:點擊數: 標簽:軟件測試模型新模型
通常情況下,一個軟件模型說明的內容主要包括,在 測試過程 中你應該考慮到哪些問題,如何對測試進行計劃,測試要達到什么目標,什么時候開始,在測試中你要用到哪些信息資源。一個好的模型可以引導你對問題進行思考,而不好的模型則只能使你誤入歧途。 這里

                      

通常情況下,一個軟件模型說明的內容主要包括,在測試過程中你應該考慮到哪些問題,如何對測試進行計劃,測試要達到什么目標,什么時候開始,在測試中你要用到哪些信息資源。一個好的模型可以引導你對問題進行思考,而不好的模型則只能使你誤入歧途。
這里我要宣稱的是,目前的大多數軟件測試模型都是不好的模型。這是因為這些測試模型僅僅是軟件開發模型的一些裝飾和補充而已。

人們一直在苦苦尋找軟件開發的模型,在創建了新的模型后,就把測試作為一個階段放在模型的后面部分。因此測試總被作為一種事后行為,測試總是被開發所驅動??偟膩碚f,我們是在檢測他們的完成品。但是,作為事后處理的測試,其驅動方式是不正確的。實際上它顯而易見地和開發過程中各種行為之間有關,測試沒有起到應有的平衡作用。這樣的測試只是檢測了開發人員做了什么,而并沒有檢測到他們是否按照規則做了什么,這樣的做法割裂了本該緊密聯系的行為,剩下的只有那些匆忙而草率的想法所帶來的傷害。
而這樣做的結果就是效果很差的、效率很低的測試。效果很差的測試將導致很多bug沒有被發現,而效率很低的測試所浪費的是成本。
在本文中,我要做2件事,其一,我要否定一個不好的模型,即V模型。我希望通過論述來表明,“單元測試”和“集成測試”這2個詞匯可以從我們的詞匯表中取消了。其二,我將描述一個更好的模型。不過首先我認為,要真正擁有一個充分合理的模型還為時尚早。我僅僅是描述了一些新模型應該符合的重要的要求。這些要求將在本文末尾處列舉。

V模型有什么問題呢?

在本文中我要把V模型作為不好的模型的典型來進行分析。我選擇V模型作為分析的典型是因為V模型是最廣為人知的測試模型。

最典型的V模型版本一般會在其開始部分對軟件開發過程進行描述,如下圖所示:

(圖1--V模型的各級開發階段)

這是古老的瀑布模型。作為開發模型,它有很多問題,不過這里不作討論。盡管它的各種狀態是我們接著要討論的大家最熟悉的V模型的基礎。我的批評意見同時也針對其它的裝飾在一些更好的開發模型之上的測試模型,例如螺旋模型[Boehm88]。
在V模型中,測試過程被加在開發過程的后半部分,如下圖所示:

(圖2--V模型示意圖)

單元測試所檢測的是,代碼的開發是否符合詳細設計的要求。集成測試所檢測的是,此前測試過的各組成部分是否能完好地結合到一起。系統測試所檢測的是,已集成在一起的產品是否符合系統規格說明書的要求。而驗收測試則檢測產品是否符合最終用戶的需求。

對于測試設計,顯而易見的是,V模型的用戶往往會把執行測試與測試設計分開對待。在開發文檔準備就緒后,就可以開始進行相關的測試設計。如下圖所示,相應的測試設計覆蓋在了相關的開發過程之上:

(圖3--將測試設計覆蓋了開發過程后的V模型)

V模型有著很吸引人的對稱外形,并且把很多人都帶入了歧途。本文將集中討論它在單元測試和集成測試中引起的問題。
為了說明的方便,這里專門制作了以下圖片,圖中包括一個單獨的單元,以及一個單元組,我稱之為子系統(subsystem)。

(圖4--一個假想的子系統)

對于一個單元應該多大才最為合適的問題,已經有過很多的討論,究竟一個單元僅僅是一個函數,一個類,還是相關的類的集合?這些討論并不影響我在這里所要闡述的觀點。我們權且認為一個單元就是一個具有最小程度的代碼塊,開發人員可以對進行獨立地討論。
V模型認為人們首先應該對每一個單元進行測試。當子系統中所有的單元都已經測試完畢,它們將被集中到一起進行測試,以驗證它們是否可以構成一個可運行的整體。
那么,如何針對單元進行測試呢?我們會查看在詳細設計中對接口的定義,或者查看源代碼,或者同時對兩者進行查看,找出符合某些測試設計中的有關準則的輸入數據來進行輸入,然后檢查結果,看其是否正確。由于各單元一般來說不能獨立地運行,所以我們不得不另外設計樁模塊(Stub)和驅動模塊(Driver),如下圖所示。

(圖5:單元及其外部的驅動模塊和樁模塊)

圖中的箭頭代表了測試的執行軌跡。這就是大多數人所說的“單元測試”。我認為這樣的方法有時候是一種不好的方法。
同樣的輸入也可以有同一子系統中的其它單元來提供,這樣,其它的單元既扮演了樁模塊,又扮演了驅動模塊。如下圖所示:

(圖6--子系統內部各單元間的測試執行軌跡)

到底選擇哪一種方法,這需要一種折衷和權衡。設計樁模塊和驅動模塊要付出多少代價?這些模塊如何進行維護?子系統是否會由此而掩蓋了一些故障?在整個子系統范圍內進行排錯的困難程度有多大?如果我們的測試直到集成測試時才真正開始,那么一些bug可能較晚才被發現。由此造成的代價同設計樁模塊和驅動模塊的代價如何比較?等等。

V模型沒有去考慮這些問題,當單元開發完成后就執行單元測試,而當自系統被集中在一起后就執行集成測試,僅此而已。令我奇怪和沮喪的是,人們從不去做一些權衡,他們已經受制于他們的模型。
因此,一個有用的模型應該允許測試人員考慮節省并推遲測試的可能性。

一個測試,如果要發現一個特定的單元中的bug,最好是在該單元保持獨立的情況下執行,并且在其外部輔以特定的樁模塊和驅動模塊。而另一種方法則是讓它作為子系統的一部分來進行測試,該測試的設計主要是為了發現集成的問題。由于一個子系統本身也需要樁模塊和驅動模塊來模擬該子系統和其它子系統的聯系,因此,單元測試和集成測試可能被推遲到至少整個系統已經部分集成的時候。在這種情況下,測試者可能通過產品的外部接口同時進行單元測試、集成測試和系統測試,同樣的,其主要目的還是為了減少總體生命周期的成本,對測試成本和延期進行測試及由此造成延期發現bug的代價成本進行權衡。據此而言,“單元測試”、“集成測試”和“系統測試”的區別已經大大削弱了。其結果可參考下圖:

(圖7--新的方法:在部分階段延遲進行單元測試和集成測試)

在上圖右邊的方塊中,最好要改成為“執行某些適當的測試并得到相應的結果”。
圖中的左邊會怎樣?考慮一下系統測試設計,它的主要根據和信息來源是是規格說明。假設你知道有2個單元處在一個特定的子系統中,它們在運行時相互聯系,并且要執行規格說明中的一個特定的聲明。為什么不在該子系統被集成時立即對此規格說明中的聲明進行測試,就象是在設計完成后立即開始測試的設計一樣呢?如果該聲明的執行和子系統外的子系統沒有任何關系,為什么還要等到整個系統完成以后再測試呢?難道越早發現bug成本越低不對嗎?
在上一張圖片中,我們用了向上指的箭頭(更有效,但在時間上有延遲)。這里還可以把箭頭往下指(在時間上提前):

(圖8--新的方法:在不同階段上提前進行測試設計)

在這種情況下,左邊的方塊中最好被標記為:“在當前信息條件和情況下可以做的任何測試設計”。這樣,當測試設計得自于系統中某一個組件的描述時,模型必須允許這樣的測試在組件被裝配之前被執行。我必須承認我的圖片非常難看,這些箭頭指得到處都是,對此我有2點說明:
1. 我們所討論的事情不是創造美,而是想要發現盡可能多的嚴重錯誤,同時盡可能地降低成本。
2. 難看的部分原因也是因為必須按照某些次序來執行的結果,亦即開發人員先提供系統描述文檔,然后測試和這些文檔進行關聯。這些文檔就象是堅實的老橡樹,而測試設計則象是細細的枝條纏繞在樹上。如果我們采用不同的原理來進行組織,圖片可能就會變得好看些。但復雜性仍不可避免,因為我們要討論的問題本身就很復雜。
V模型失敗的原因是它把系統開發過程劃分為具有固定邊界的不同階段,這使得人們很難跨過這些邊界來采集測試所需要的信息。有些測試應該執行得更早些,有些測試則需要延后進行。而且,它也阻礙了你從系統描述的不同階段中取得信息進行綜合。例如,某些組織有時執行這樣的做法,即對完成的工作進行簽署。這樣的規定也擴展到系統測試的設計。簽署表示已經過評估,該測試設計工作已經完成,除非對應的設計文檔改變,否則就不會被修訂。如果同這些測試相關的信息后來被重新挖掘和認識,例如,架構設計表明有些測試是多余的,或者,詳細設計表明有一個內部的邊界可以和已存在的系統測試組合在一起進行測試的話,那么實際上還需要繼續調整原來的系統測試設計。
因此,模型必須允許利用不同來源的綜合信息進行個別的測試設計。另外,模型還應該允許在新的信息來源出現后重新進行測試的設計。

一個不同的模型

讓我們來看本文的第二項內容,一個不同的模型。
很多時候人們把代碼移交給其他人,并且說:“希望你能接受和喜歡它?!边@不僅發生在將整個項目放在一張光盤中交給客戶的時候,也發生在項目內部。
例如,一個小組對另一個小組說:“我們已經完成了為COMM庫加入了對XML的支持。源代碼現在已經放在master庫中,可執行庫則已經加入到集成與創建的環境中。XARG小組的工作已經沒有什么阻礙了,隨時去取吧?!?BR>某個程序員檢查了bug的修改并且發出郵件:“我已經修改了Bug列表中的那個Bug,很抱歉!”至此,早先受該問題影響的其它代碼就可以繼續處理了。
在這些情況下,人們要把代碼移交給其它人,其中有可能會存在一些影響。測試人員需要干預這個過程。在移交之前,測試人員應執行這些代碼,發現其中的bug(影響),并且提出問題:“你確實要提交這些嗎?”由此,移交的內容可能會被延期,直到bug被修復好。
盡管你還要做其它的各種測試,這項測試仍然是很基本的測試工作。如果你沒有做這樣的測試,就不能算是合格的測試人員。
我們的測試模型必須包含這一重要的現實需要:針對代碼移交的測試。由此,測試模型應提示進行針對每一次代碼移交的測試。
就讓我以支持XML的COMM庫作為例子。這里存在著一個小組把代碼移交給XARG小組以進行項目的余下部分。那么誰會遭受影響?

要將這些支持XML的代碼直接進行使用的XARG小組可能會立即受到影響;
這可能會在稍后影響到市場人員,他們要在一個行業展示會議上為“合作伙伴發行”版本提供產品演示和宣傳,而XML支持是影響他們銷售的重要部分;
還有,它可能損害采納我們的產品的合作伙伴。
現在我們可以提出一些有趣的關于測試計劃的問題了。最簡單的可以做的事情是,在移交的時候立即執行XML支持的完整測試。(“完整”的含義是,為此設計盡可能多的測試)但也許一些XML特性并不是XARG小組所需要的,因此可以把它們放在合作伙伴版本封版(下圖中的“Partner Release”)的測試中去。這意味著可以把一些XML相關測試放到稍后的移交過程中去?;蛘呋谄渌碛?,例如在近階段有其它的測試任務要執行。而XARG小組則要因XML中的bug修復而延遲一小段時間。
我們的測試計劃所表示的進度可以通過在開發的時間線上進行注解的方式來表現,如下圖所示:

(圖9:添加在開發計劃之上的測試計劃)

我們應嚴格地圍繞在XML支持的功能交接的時段里進行測試。測試設計和測試支持工作要早于測試執行。而另外的XML測試則要延遲到基于整個項目范圍的“代碼完成”(圖中的“Code Complete”里程碑),或者要等到全部的子系統被集中在一起,而且整個產品為了行業會議而在經過穩定化處理后創建了版本(圖中的“Partner Release”里程碑)。
顯然,有兩項內容沒有包含在代碼完成里程碑中:

還有大量其它的測試工作(包括設計、工具選用)。這些工作可能因為COMM以外的子系統的交接而延期。
而且,還有用于完成里程碑中所規定的某些風險的測試,例如,可能還有一組用于運行市場人員的演示Demo腳本的測試,包括她可能在無意中引起的偏離。其目的是要避免這樣的情況,即當她站在1000人的觀眾面前時,她還僅僅是第一次以某種特定的順序來輸入數據。
一些首次交接時進行的XML測試需要在代碼完成里程碑上再次執行。
我的觀點是,測試計劃是由很多困難的決定所組成,這些決定包括人員組織安排、機器資源配置、測試設計的時間定位、測試支持代碼的數量、哪些測試要做自動化,等等。這些決定應根據單獨的交接中的內容信息來作出。如果僅有一次交接,那么你可以更順利一些。測試計劃還應繼續考慮以下問題:

1. 風險分析,誰會因此受到損害,以什么方式?

2. 選定一種測試途徑來定位特定的風險。

3. 對測試設計和執行的周期和成本進行估計。

4. 在項目進度上的特定位置,將計劃納入執行的行動:

A. 開始對測試進行設計…
B. … 同時設計和創建一些支持測試的代碼…
C. … 在全部測試完成以前就執行部分的測試,因為可能存在不只一次的交接,在每一次交接的測試規劃中,可能存在一些潛在的復雜的相互影響。工作安排不得不進行一些調整以達到相互間的平衡。測試支持代碼和工具需要在各項任務中得到共享。你還必須考慮到在什么程度上讓那些為早先的交接所設計的測試在以后重新執行,等等。
這看起來很復雜??瓷先ニ坪跤刑嗟膬热菪枰?,而且太多的內容可能被忽略。也許你認為我是在要求你要對每一次交接來執行IEEE 829 [IEEE98]中關于測試計劃的要求,然后把它們合并為一份貫穿整個項目的針對交接進行測試的測試計劃。
是,也不是。思考問題總是要占用時間的。太多的計劃可能會減少結果的產出。在有些時候,你需要做的是停止計劃并開始行動。例如,你無法思考并描述每一個bug修復,盡管bug修復也是一種交接。
但是bug修復是實際工作中現實存在的問題??傮w項目計劃中應該包含bug修復。需要強調的是,你應該有一個默認的bug修改處理的標準過程,該過程應包括運行于每一個提交的bug修復的驗證過程。你還需要努力地去思考問題。很多時候,各項驗證是被放在一起同時進行并完成的。
比較現實地來說,一個模型應該允許一些機械式行為,例如,“不管是哪一個X類型的交接,都要執行下列操作”。同時我們鼓勵對特定的交接執行剛剛夠的檢查,對于風險越小的交接,就越可以采用機械式的測試行為。
一個明確考慮到基本的測試現實的模型肯定會比忽略這些現實或者把你的工作復雜性完全抽象化的模型做得更好。文檔則是另一個例子。
我還沒有提到需求及規格說明書,或者設計文檔。某個交接中產生的一系列變化會引起很多爭議。這些文檔所扮演的角色是什么呢?它們常常是這么被使用的:

(圖10:測試中對開發文檔的利用)

文檔可以指導你在一個交接變化時如何作出反應。如果你有一份很好的需求文檔,它可能是產品所解決的問題的描述,盡管也許不是很直接。它可以幫助你對風險進行分析。一份好的規格說明應對系統的行為進行描述。這將幫助你把測試方法轉化為具體的測試。一份好的架構設計則可以幫助你理解變化可能引起的幾種不同的情況:系統的其它部分會受到怎樣的影響?什么測試需要再次進行?
我并不是經常能看到好的文檔。需求文檔常常象是市場銷售用的系統特性列表。規格說明書有時就象是在代碼完成后提交的用戶手冊文件。而設計文檔經常不存在。

好了,通過針對交接所引起的變化的集中討論,我已把測試過程和軟件開發過程相對地分離開了。如果文檔中關于“XML支持功能加入到COMM”的描述很薄弱的話,我會盡自己所知來進行盡可能好的測試設計。然后,假如在項目后期,XML相關的用戶文檔出來了,我就可以對后來再次提交的交接增加相關的測試。假如市場需求改變了,她們經常會這么做,我還會在此后增加或者去除一些測試。所有這一切看起來是這樣的:

(圖11--在文檔不完整的條件下進行測試,并在后期補充測試)

這樣,雖然項目文檔總是不到位,而且經常延遲提交,測試的效果也因此常常被降低,我們還是要避免測試受到項目文檔的制約。
頭腦靈活的測試人員并不過于相信文檔。畢竟,總是人在犯錯誤。那么,難道不是人在寫這些文檔嗎?
由于“正式的”文檔是很薄弱的,測試模型必須明確地鼓勵在測試過程中使用項目文檔之外的各種不同信息來源。
測試人員必須和程序員、用戶、市場人員、技術作者以及任何的可能為實現更好測試提供線索的人進行交流。測試人員還應該努力把自己沉浸在某些技術所構建的氛圍中。例如,我希望測試人員在做XML測試工作時常去訪問W3組織的XML地址(http://www.w3.org/XML/)以及其它XML站點、郵件列表,甚至包括比較特別的 如Dave Winer的DaveNet/腳本新聞(http://www.scripting.com/)。這些資源并不是所謂的“輔助通道”,而是可以被列入計劃和進度日程的資源。
另外,所執行的測試本身也是一種有用的信息的資源。好的測試人員會仔細閱讀bug報告,因為這些報告講授了系統所存在的薄弱之處。特別地,這些報告還暗示了一些正式的架構設計所沒有提供的架構上的策略。執行測試的行為應該產生一些新的測試想法。如果模型沒有考慮到這些,那么它就是一個落后的模型。
因此,測試模型應該包含反饋的循環,讓測試設計可以考慮到,在運行測試時還可以繼續發現到更多的測試內容。
在我們的工作中,真正的復雜性來自于所有計劃的執行都處于一個不確定的、容易忽略的環境里。代碼并不是唯一在不斷變化的東西。而計劃日程也在改變。新的功能擴充會帶來新的里程碑。某些功能會從當前版本中去除。在開發過程中,所有人--市場人員、開發人員和測試人員,都會逐漸對諸如“產品究竟提供什么”這樣的問題有越來越清晰的了解。在這些情形下,我們怎么能說測試計劃的第一個版本會是完全正確的呢?
因此,模型應該要求測試計劃人制定明確的規定,對已交接的交接內容,新的交接,以及交接內容的變更進行負責。

總結

V模型有以下致命的缺陷,其它模型實際上也與此相似:

1. 忽略了這樣的事實情況,即軟件開發是由一系列的交接所組成,每一次交接內容都改變了前一次交接的行為。

2. 依賴于開發文檔的存在,及文檔的精確性、完整性,并且沒有對時間進行限制。

3. 認定一種測試的設計是依據某一個單獨的文檔,而不包括根據其前后階段的文檔的修改而作相應修改。

4. 認定這些依賴于某個單獨文檔的測試一定要在一起執行。

我大致描述了一個替代模型,但還不夠精細。它考慮到了代碼的交接和里程碑。對測試成本控制作了以下明確描述:
測試設計的目標是定義好可能發現bug的測試輸入,而測試執行的目標是以各種方式加入這些數據,并檢驗結果,由此來降低整個生命周期的成本。

我們的模型假設軟件產品總是不完美的,開發過程中有很多變更,而且對產品的測試也是一個不斷學習的過程。
過去,我很少考慮到模型。表面上我一直還在用V模型。雖然我按此制訂計劃,但我總是還要花費很多額外的精力和時間來考慮模型中沒有提到的方面。換言之,模型造成了一些阻礙,因此我有必要對此進行研究。
對一個新的模型來說,對模型所提出的要求必須非常明確,這就象業務需求對產品開發非常重要一樣。我希望自己對本文中所提倡的模型的要求的描述能夠和V模型中的描述一樣精確,并具有同樣的指導意義。

理想的測試模型應該包括下列要求:

1. 使測試對項目中的每一次代碼交接有所反應。

2. 要求測試計劃人制定明確的規定,對已交接的交接內容,新的交接,以及交接內容的變更進行負責。

3. 在測試設計中,除了使用項目文檔外,還應明確鼓勵使用其它各種信息,這些信息有不同來源。

4. 事實上項目文檔總是不到位,而且經常延遲提交,測試的效果也因此常常被降低。但我們還是要盡量避免測試受到項目文檔的制約。

5. 允許根據多種來源提供的綜合信息來設計一些獨立的測試。

6. 讓測試被重新設計,以新的信息形式進行表現。

7. 包含反饋的循環,讓測試設計可以考慮到,在運行測試時還可以繼續發現到更多的測試內容。

8. 讓測試人員認識到,避免測試的延遲可以節省成本。

9. 在組件被組裝到程序中去之前對組件的執行進行測試。

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

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