《軟件工程理論與實踐》-第十二章_第1頁
《軟件工程理論與實踐》-第十二章_第2頁
《軟件工程理論與實踐》-第十二章_第3頁
《軟件工程理論與實踐》-第十二章_第4頁
《軟件工程理論與實踐》-第十二章_第5頁
已閱讀5頁,還剩66頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第12章面向對象測試

【目標】

本章對面向對象的側試進行介紹。讀完本章,讀者將了解以下內容。傳統側試方法和面向側試設計方法的不同;面向對象分析與設計的模型;面向對象的側試策略;面向對象軟件側試用例設計;面向對象的集成側試。上一頁下一頁返回第12章面向對象測試

在前面帝節中學習了測試的目標,簡單地說,在現實可行的時間跨度內應用可管理的工作量去發現盡可能多的錯誤。雖然對面向對象軟件而言,這個基本目標仍保持不變,但是面向對象程序的性質改變了測試的策略和測試戰術。有人可能爭辯說,隨著oon和(oon的成熟,更多的設計模式復用將減輕面向對象系統的繁重測試量。準確地說,其反面才是真的。針對該問題有如下討論。每次復用是一個新的使用語境,要謹慎地重新測試。為了獲得面向對象系統的高可靠性,似乎可能將需要更多而不是更少的測試。為了充分地測試面向對象系統,必須做好3件事:①測試的定義必須擴大包括用于OOA和OOD模型的錯誤發現技術。②單元和集成測試策略必須有很大的改變。③測試用例的設計必須考慮面向對象軟件的獨特特征。上一頁下一頁返回12.1擴大測試的視角

面向對象軟件的構造從分析和設計模型的創建開始。因為面向對象軟件工程范型的演化性質,模型從對系統需求相對非正式的表示開始,逐步演化為詳細的類模型、類連接和關系、系統設計和分配,以及對象設計(通過消息序列的對象連接模型)。在每個階段,測試模型,以試圖在錯誤傳播到下一次遞進前發現錯誤。可以爭辯說面向對象分析和設計模型的復審是特別有用的,因為相同的語義結構(如類、屬性、操作、消息)出現在分析、設計和代碼階段,因此,在分析階段發現的類屬性定義中的問題將遏止當問題直至設計或編碼階段(或甚至到下一次分析迭代)才被發現所帶來的副作用。下一頁返回12.1擴大測試的視角

例如,考慮一個類,在第一次OOA迭代時定義了其中一系列屬性,一個外來的無關屬性被附于該類(由于對問題域的錯誤理解),然后定義兩個操縱該屬性的操作。在復審時,一個領域專家指出該問題。通過在本階段刪除該無關屬性,可在分析過程中避免下面的問題和不必要的努力。

(1)特殊的子類可能已經被生成以適應不必要的屬性或它的例外。涉及不必要的子類的創建工作可被避免。

(2)類定義的錯誤解釋可能導致不正確的或無關的類關系。

(3)系統或它的類的行為可能被不適當地刻畫以適應該無關屬性。如果問題未在分析過程中被發現并進一步向前傳播,在設計中可能產生下面的問題(如盡早復審,應已避免的)。上一頁下一頁返回12.1擴大測試的視角

(1)在系統設計階段可能將類不合適的分配到子系統和/或任務。

(2)可能花費不必要的工作去創建針對無關屬性的操作的過程設計。

(3)消息模型將是不正確的(因為必須為無關的操作設計消息)。如果問題在設計階段仍未被檢測到,并傳送到編碼活動中,則將花費大量的工作努力和精力去生成那些實現一個不必要的屬性、兩個不必要的操作、馬伙動對象間通信的消息以及很多其他相關問題的代碼。此外,類的測試將花費更多的時間。一旦問題最終被發現,必須對系統進行修改,從而引致由于修改而產生到作用的很大的潛在可能性。

上一頁下一頁返回12.1擴大測試的視角

在它們的開發的后面階段,OOA和OOD模型提供了關于系統的結構和行為的實質性信息,為此,這些模型應該在生成代碼前經受嚴格的復審。所有面向對象模型應該被測試(在這個語境內,術語“測試”代表正規的技術復審),以保證在模型的語法、語義和語用的語境內的正確性、完整性和一致性。上一頁返回12.2測試OOA和OOD模型

分析和設計模型不能進行傳統意義上的測試,因為它們不能被執行。然而,正式的技術復審可被用于檢查分析和設計模型的正確性和一致性。

1.OOA和OOD模型的正確性用于表示分析和設計模型的符號體系和語法將是和為項目選定的特定分析和設計方法聯系的,因此,語法正確性基于符號是否合適使用,而且對每個模型復審以保證保持合適的建模約定。在分析和設計階段,語義正確性必須基于模型對現實世界問題域的符合度來判斷,如果模型精確地反映了現實世界(到這樣一個細節程度:它對模型復審時所處的開發階段是合適的),則它是語義正確的。為了確定是否模型確實在事實上反映了現實世界,它應該被送給問題域專家,專家將檢查類定義和類層次以發現遺漏和含混。評估類關系(實例連接)以確定它們是否精確地反映了現實世界的對象連接。下一頁返回12.2測試OOA和OOD模型

2.OOA和OOD模型的一致性對OOA和OOD模型的一致性判斷可以通過“考慮模型中實體間的關系。一個不一致的模型在某一部分有表示,但未在模型的其他部分正確地反應”。為了評估一致性,應該檢查每個類及其和其他類的連接。可運用類責任協作者(CRC)模型和對象關系圖。如在第6章提到,CRC模型由CRC索引卡片構成,每個CRC卡片列出類名、類的責任(操作),以及其協作者(其他類,類向它們發送消息并依賴于它們完成自己的責任)。協作蘊含了在面向對象系統的類之間的一系列關系(即連接),對象關系模型提供了類之間連接的圖形表示。所有這些信息可以從OOA模型得到。為了評估類模型,推薦采用以下面步驟得到。上一頁下一頁返回12.2測試OOA和OOD模型

(1)再次考察CRC模型和對象一關系模型,進行交叉檢查以保證由oon模型所蘊涵的協作適當地反應在二者中。

(2)檢查每個CRC索引卡片的描述以確定是否某被受權的責任是協作者的定義的一部分。

(3)反轉該連接以保證每個被請求服務的協作者正在接收來自合理源的請求。

(4)使用在第(3)步檢查的反轉連接,確定是否可能需要其他的類或責任是否被合適地在類間分組。

(5)確定是否被廣泛請求的責任可被組合為單個的責任。

(6)步驟(1)~(5)被迭代地應用到每個類,并貫穿OOA模型的每次演化。

上一頁下一頁返回12.2測試OOA和OOD模型

一旦已經創建了設計模型,也應該進行對系統設計和對象設計的復審。系統設計描述了構成產品的子系統、子系統被分配到處理器的方式,以及類到子系統的分配。對象模型表示了每個類的細節和實現類間的協作所必需的消息序列活動。

通過檢查在OOA階段開發的對象行為模型,和映射需要的系統行為到被設計用于完成該行為的子系統來進行系統設計的復審。也在系統行為的語境內復審并發性和任務分配,評估系統的行為狀態以確定哪些行為并發地存在。對象模型應該針對對象一關系網絡來測試,以保證所有設計對象包含為實現為每張CRC索引卡片定義的協作所必須的屬性和操作。此外,使用傳統的檢查技術來復雜操作細節的詳細規約(即實現操作的算法)。上一頁返回12.3面向對象的測試策略

傳統的測試計算機軟件的策略是從“小型測試”開始,逐步走向“大型測試”。用軟件測試的行話來陳述,從單元測試開始,然后逐步進人集成測試,最后是有效性和系統測試。在傳統應用中,單元測試集中在最小的可編譯程序單位一子程序(如模塊、子例程、進程),一旦這些單元均被獨立測試后,它被集成進程序結構中,這時要進行一系列的回歸測試以發現由于模塊的接口所帶來的錯誤和新單元加人所導致的副作用,最后,系統被作為一個整體測試以保證發現在需求中的錯誤。

1.在面向對象語境中的單元測試當考慮面向對象軟件時,單元的概念發生了變化。封裝馭動了類和對象的定義,這意味著每個類和類的實例(對象)包裝了屬性(數據)和操縱這些數據的操作(也稱為方法或服務)。而不是個體的模塊。最小的下一頁返回12.3面向對象的測試策略

可測試單位是封裝的類或對象,類包含一組不同的操作,并且某特殊操作可能作為一組不同類的一部分存在,因此,單元測試的意義發生了較大變化。

我們不再孤立地測試單個操作(傳統的單元測試觀點),而是將操作作為類的一部分。作為一個例子,考慮一個類層次,其中操作X針對超類定義并被一組子類繼承,每個子類使用操作X,但是它被應用于為每個子類定義的私有屬性和操作的環境內。因為操作X被使用的語境有微妙的不同,有必要在每個子類的語境內測試操作X。這意味著在面向對象的語境內在真空中測試操作X(即傳統的單元測試方法)是無效的。上一頁下一頁返回12.3面向對象的測試策略

對面向對象軟件的類測試等價于傳統軟件的單元測試。和傳統軟件的單元測試不一樣,它往往關注模塊的算法細節和模塊接口間流動的數據,面向對象軟件的類測試是由封裝在類中的操作和類的狀態行為所馭動的。

單元測試是在軟件開發過程中要進行的最低級別的測試活動,在單元測試活動中,軟件的獨立單元將在與程序的其他部分相隔離的情況下進行測試。在程序設計過程中會有許多種測試,單元測試只是其中的一種,單元測試并不能保證程序是完美無缺的,但是在所有的測試中,單元測試是第一個環節,也是最重要的一個環節。單元測試是一種由程序員自行測試的工作。簡單地說,單元測試就是測試代碼撰寫者依據其所設想的方式執行是否產生了預期的結果。

上一頁下一頁返回12.3面向對象的測試策略

為什么需要單元測試?當編寫項目的時刻,如果假設底層的代碼是正確無誤的,那么先是高層代碼中使用了底層代碼;然后這些高層代碼又被更高層的代碼所使用,如此往復。當基本的底層代碼不再可靠時,那么必須的改動就無法只局限在底層。雖然可以修正底層的問題,但是這些對底層代碼的修改必然會影響到高層代碼。于是,一個對底層代碼的修正,可能會導致對幾乎所有代碼的一連串改動,從而使修改越來越多,也越來越復雜。從而使整個項目也以失敗告終。所以,單元測試的核心內涵就是:利用簡單有效的技術使代碼變得更加完美。上一頁下一頁返回12.3面向對象的測試策略

傳統的單元測試是針對程序的函數、過程或完成某一定功能的程序塊。沿用單元測試的概念,實際測試類成員函數。一些傳統的測試方法在面向對象的單元測試中都可以使用。如等價類劃分法、因果圖法、邊值分析法、邏輯覆蓋法、路徑分析法、程序插裝法等。單元測試一般建議由程序員完成。用于單元級測試進行的測試分析(提出相應的測試要求)和測試用例(選擇適當的輸入,達到測試要求),規模和難度等均遠小于后面將介紹的對整個系統的測試分析和測試用例,而且強調對語句應該有100%的執行代碼覆蓋率。在設計測試用例選擇輸入數據時,可以基于以下兩個假設。上一頁下一頁返回12.3面向對象的測試策略

(1)如果函數(程序)對某一類輸入中的一個數據正確執行,對同類中的其他輸入也能正確執行。

(2)如果函數(程序)對某一復雜度的輸入正確執行,對更高復雜度的輸入也能正確執行。例如需要選擇字符串作為輸入時,基于本假設,就無須計較于字符串的長度。除非字符串的長度是要求固定的,如IP地址字符串。在面向對象程序中,類成員函數通常都很小,功能單一,函數間的調用頻繁,容易出現一些不宜發現的錯誤。例如:if(-1==write(fid,buffer,amount))error_out();

該語句沒有全面檢查write()的返回值,無意中斷然假設了只有數據被完全寫人和沒有寫人兩種情況。當測試也忽略了數據部分寫人的情況,就給程序遺留了隱患。上一頁下一頁返回12.3面向對象的測試策略

按程序的設計,使用函數5trrchr()查找最后的匹配字符,但誤程序中寫成了函數Strchr(),使程序功能實現時查找的是第一個匹配字符。又如,程序中將if(strncmp(strl,str2,strlcn(strl)))誤寫成了if(strncmp(strl,str2,strlen(str2)))如果測試用例中使用的數據ctrl和str2長度一樣,就無法檢測出。因此,在做測試分析和設計測試用例時,應該注意面向對象程序的這個特點,仔細地進行測試分析和設計測試用例,尤其是針對以函數返回值作為條件判斷選擇,字符串操作等情況。面向對象編程的特性使得對成員函數的測試,又不完全等同于傳統的函數或過程測試。尤其是繼承特性和多態特性,使子類繼承或過載的父類成員函數出現了傳統測試中未遇見的問題。從以下兩方面來考慮。上一頁下一頁返回12.3面向對象的測試策略

幼繼承的成員函數是否都不需要測試?

對父類中已經測試過的成員函數,兩種情況需要在子類中重新測試:①繼承的成員函數在子類中做了改動。②成員函數調用了改動過的成員函數的部分。例如:

假設父類Bass有兩個成員函數:Inherited)和Redefined(),子類Derived只對Rcdcfincd()做了改動。Derived::Redefined()顯然需要重新測試。對于Derived:In-hcritcd(),如果它有調用Redefined()的語句(如x=x/Redefined()),就需要重新測試,反之,無此必要。

2)對父類的測試是否能照搬到子類?援用上面的假設,Base::Redefined()和Derived::Redefined()已經是不同的成員函數,它們有不同的服務說明和執行。對此,照理應該對Derived:Redefined()重新測試分析,設計測試用例。但由于面向對上一頁下一頁返回12.3面向對象的測試策略

象的繼承使得兩個函數有相似,故只需在Base:Rcdcfincd()的測試要求和測試用例上添加對Derived::Rcdfincd()新的測試要求和增補相應的測試用例。例如:Base:Redefined()含有如下語句。If(valuc}0)message("less")elseif(value==0)message(“equal”);elsemessage("more")Derived:Rcdfincd()中定義為:If(valuc<0)message("less")elseif(value==0)message("Itisequal");else{message("more");if(value=88)message("luck");}上一頁下一頁返回12.3面向對象的測試策略

在原有的測試上,對Derived::Rcdfincd()的測試只需做如下改動:將value==0的測試結果期望改動;增加value=-88的測試。多態有幾種不同的形式,如參數多態、包含多態、過載多態。包含多態和過載多態在面向對象語言中通常體現在子類與父類的繼承關系,對這兩種多態的測試參見上述對父類成員函數繼承和過載的論述。包含多態雖然使成員函數的參數可有多種類型,但通常只是增加了測試的繁雜。對具有包含多態的成員函數測試時,只需要在原有的測試分析和基礎上擴大測試用例中輸入數據的類型的考慮。

2.在面向對象語境中的集成測試因為面向對象軟件沒有層次的控制結構,傳統的自頂向下和自底向上集成策略就沒有意義,此外,一次集成一個操作到類中(傳統的增上一頁下一頁返回12.3面向對象的測試策略

量集成方法)經常是不可能的,這是由于“構成類的成分的直接和間接的交互”。傳統的集成測試,一般可以在部分程序編譯完成的情況下進行。而對于面向對象程序,相互調用的功能是散布在程序的不同類中,類通過消息相互作用申請和提供服務。類的行為與它的狀態密切相關,狀態不僅僅體現在類數據成員的值上,也許還包括其他類中的狀態信息。由此可見,類相互依賴極其緊密,根本無法在編譯不完全的程序上對類進行測試。所以,面向對象的集成測試通常需要在整個程序編譯完成后進行。此外,面向對象程序具有動態特性,程序的控制流往往無法確定,因此也只能對整個編譯后的程序做基于黑盒子的集成測試。上一頁下一頁返回12.3面向對象的測試策略

對面向對象軟件的集成測試有兩種不同策略,第一種稱為基于線程的測試,集成對回應系統的一個輸入或事件所需的一組類,每個線程被集成并分別測試,應用回歸測試以保證沒有產生副作用。第二種稱為基于使用的測試,通過測試那些幾乎不使用服務器類的類(稱為獨立類)而開始構造系統,在獨立類測試完成后,下一層的使用獨立類的類(稱為依賴類)被測試。這個依賴類層次的測試序列一直持續到構造完整個系統。序列和傳統集成不同,使用馭動器和樁作為替代操作是要盡可能避免的。

集群測試是面向對象軟件集成測試的一步,這里一群協作類(通過檢查CRC和對象關系模型而確定的)通過設計試圖發現協作中的錯誤的測試用例而被測試。

上一頁下一頁返回12.3面向對象的測試策略

面向對象的集成測試能夠檢測出相對獨立的單元測試無法檢測出的那些類相互作用時才會產生的錯誤。基于單元測試對成員函數行為正確性的保證,集成測試只關注于系統的結構和內部的相互作用。面向對象的集成測試可以分成兩步進行:先進行靜態測試,再進行動態測試。靜態測試主要針對程序的結構進行,檢測程序結構是否符合設計要求。現在流行的一些測試軟件都能提供一種稱為“可逆性工程”的功能,即通過原程序得到類關系圖和函數功能調用關系圖,例如InternationalSoftwareautomation公司的Panorama-2forWin-dows95,Rational公司的RoseC++analyzer等,將“可逆性工程”得到的結果與(OOD的結果相比較,檢測程序結構和實現上是否有缺陷。換句話說,通過這種方法檢測OOP是否達到了設計要求。

上一頁下一頁返回12.3面向對象的測試策略

動態測試設計測試用例時,通常需要上述的功能調用結構圖、類關系圖或者實體關系圖為參考,確定不需要被重復測試的部分,從而優化測試用例,減少測試工作量,使得進行的測試能夠達到一定覆蓋標準。測試所要達到的覆蓋標準可以是:達到類所有的服務要求或服務提供的一定覆蓋率;依據類間傳遞的消息,達到對所有執行線程的一定覆蓋率;達到類的所有狀態的一定覆蓋率等。同時也可以考慮使用現有的一些測試工具來得到程序代碼執行的覆蓋率。具體設計測試用例,可參考下列步驟。

(1)先選定檢測的類,參考OOD分析結果,仔細找出類的狀態和相應的行為,類或成員函數間傳遞的消息,輸入或輸出的界定等。

(2)確定覆蓋標準。上一頁下一頁返回12.3面向對象的測試策略

(3)利用結構關系圖確定待測類的所有關聯。

(4)根據程序中類的對象構造測試用例,確認使用什么輸入激發類的狀態、使用類的服務和期望產生什么行為等。值得注意的是,設計測試用例時,不但要設計確認類功能滿足的輸入,還應該有意識地設計一些被禁止的例子,確認類是否有不合法的行為產生,如發送與類狀態不相適應的消息,要求不相適應的服務等。根據具體情況,動態的集成測試,有時也可以通過系統測試完成。

3.在面向對象語境中的有效性測試在有效性或系統層次,類連接的細節消失了。和傳統有效性一樣,面向對象軟件的有效性集中在用戶可見的動作和用戶可識別的系統輸上一頁下一頁返回12.3面向對象的測試策略

出。為了協助有效性測試的導出,測試人員應該利用作為分析模型一部分的用例,用例提供了在用戶交互需求中很可能發現錯誤的一個場景。傳統的黑盒測試方法可被用于馭動有效性測試,此外,測試用例可以從對象行為模型和作為(OOA的一部分的事件流圖中導出。上一頁返回12.4面向對象軟件的測試用例設計

面向對象軟件的測試用例設計方法還正處于成型期,然而,已經有一些對面向對象測試用例設計的方法建議。

(1)每個測試用例應該被唯一標識,并且和將被測試的類顯式地相關聯。

(2)應該陳述測試的目的。

(3)對每個測試應該開發一組測試步驟,應該包含以下幾個方面。

@將被測試的對象的一組特定狀態。⑥將作為測試的結果使用的一組消息和操作。

@當測試對象時可能產生的一組例外。④一組外部條件(即為了適當地進行測試而必須存在的軟件的外部環境的變化)。

@輔助理解或實現測試的補充信息。下一頁返回12.4面向對象軟件的測試用例設計

1.面向對象概念的測試用例設計的含義如我們已經看到的,面向對象類是測試用例設計的目標。因為屬性和操作是被封裝的,對類之外操作的測試通常是徒勞的。雖然封裝是面向對象的本質設計概念,但是‘已可能會成為測試的小障礙。測試需要對對象的具體和抽象狀態的報告,然而,封裝卻使得這些信息在某種程度上難于獲得。除非提供了內置操作來報告類屬性的值,否則,對對象的狀態快照是難以獲得的。繼承也造成了對測試用例設計者的挑戰。我們已知道,即使是徹底復用的,對每個新的使用語境也需要重測試。此外,多重繼承增加了需要測試的語境數量從而使測試進一步復雜化。如果從超類導出的子類被用于相同的問題域,有可能對超類導出的測試用例集可以用于子類的測試,然而,如果子類被用于完全不同的語境,則超類的測試用例將沒有多大用處,必須設計新的測試用例集。上一頁下一頁返回12.4面向對象軟件的測試用例設計

2.傳統測試用例設計方法的可用性在前面章節描述的自盒測試方法可用于對為類定義的操作的測試,基本路徑、循環測試或數據流技術可以幫助保證已經測試了操作中的每一條語句,然而,很多類操作的簡潔結構導致某些人認為:將用于自盒測試的工作量用于類級別的測試可能會更好。黑盒測試方法就像對傳統軟件工程方法開發的系統和對面向對象系統同樣適用的,如在本章前面看到的,用例可以為黑盒及基于狀態的測試的設計提供有用的輸入。和傳統測試用例設計不同,傳統測試是由軟件的輸入加工輸出視圖或個體模塊的算法細節馭動的,面向對象測試關注于設計合適的操作序列以測試類的狀態。

上一頁下一頁返回12.4面向對象軟件的測試用例設計

測試用例目前沒有經典的定義。比較通常的說法是:指對一項特定的軟件產品進行測試任務的描述,體現測試方案、方法、技術和策略。內容包括測試目標、測試環境、輸入折抿、測試步驟、預期結集、測試腳本。并形成文檔。

不同類別的軟件,測試用例是不同的。不同于諸如系統、工具、控制、游戲軟件,管理軟件的用戶需求更加不統一,變化更大、更快。筆者主要從事企業管理軟件的測試。因此我們的做法是把測試數據和測試腳本從測試用例中劃分出來。測試用例更趨于是針對軟件產品的功能、業務規則和業務處理所設計的測試方案。對軟件的每個特定功能或運行操作路徑的測試構成了一個個測試用例。上一頁下一頁返回12.4面向對象軟件的測試用例設計

要使最終用戶對軟件感到滿意,最有力的舉措就是對最終用戶的期望加以明確闡述,以便對這些期望進行核實并確認其有效性。測試用例反映了要核實的需求。然而,核實這些需求可能通過不同的方式并由不同的測試人員來實施。例如,執行軟件以便驗證它的功能和性能,這項操作可能由某個測試人員采用自動測試技術來實現;而市場占有率和銷售數據(以及產品需求),只能通過評測產品和竟爭銷售數據來完成。

確定測試用例之所以很重要,原因有以下幾方面。

(1)測試用例構成了設計和制訂測試過程的基礎。

(2)測試的“深度”與測試用例的數量成比例。由于每個測試用例反映不同的場景、條件或經由產品的事件流,因而,隨著測試用例數量的增加,您對產品質量和測試流程也就越有信心。上一頁下一頁返回12.4面向對象軟件的測試用例設計

(3)判斷測試是否完全的一個主要評測方法是基于需求的覆蓋,而這又是以確定、實施和/或執行的測試用例的數量為依據的。類似“95%的關鍵測試用例已得以執行和驗證”的說明,遠比“我們已完成95%的測試”更有意義。

(4)測試工作量與測試用例的數量成比例。根據全面且細化的測試用例,可以更準確地估計測試周期各連續階段的時間安排。

(5)測試設計和開發的類型以及所需的資源主要都受控于測試用例。

(6)測試用例通常根據它們所關聯關系的測試類型或測試需求來分類,而且將隨類型和需求進行相應的改變。最佳方案是為每個測試需求至少編制兩個測試用例:一個測試用例用于證明該需求已經滿足,通常稱為正面測試用例;另一個測試用例反映某個無法接受、反常或意外的條件或數據,用于論證只有在所需條件下才能夠滿足該需求,這個測試用例稱為負面測試用例。上一頁下一頁返回12.4面向對象軟件的測試用例設計

3.基于故障的測試在面向對象系統中基于故障的測試的目標是設計最有可能發現似乎可能的故障的測試。因為產品或系統必須符合客戶需求,因此,完成基于故障的測試所需的初步計劃是從分析模型開始的。測試人員查找似乎可能的故障(即系統實現中有可能產生錯誤的方面),為了確定是否存在這些故障,設計測試用例以測試設計或代碼。考慮一個簡單的例子。軟件工程師經常在問題的邊界處犯錯誤,例如,當測試SQRT操作(該操作對負數返回錯誤)時,嘗試邊界一個靠近零的負數和零本身,“零本身”用于檢查是否程序員犯了如下錯誤:if(x>0)calculate_the_square_root();而不是正確的:上一頁下一頁返回12.4面向對象軟件的測試用例設計

if(x>=0)calculate_the_square_root()作為另一個例子,考慮布爾表達式:if(a&&bllc)

多條件測試和相關的用于探查在該表達式中可能存在的故障的技術,如:“&&”應該是“11"“!”在需要處被省去,應該有括號包圍“!b11"。對每個可能的故障,設計迫使不正確的表達式失敗的測試用例。在上面的表達式中,(a=0,b=0,c=0)將使得表達式得到預估的“假”值,如果“己己”已改為“11",則該代碼做了錯誤的事情,有可能分叉到錯誤的路徑。當然,這些技術的有效性依賴于測試人員如何感覺“似乎可能的故障”,如果面向對象系統中的真實故障被感覺為“難以置信的”,則本上一頁下一頁返回12.4面向對象軟件的測試用例設計

方法實質上不比任何隨機測試技術好。然而,如果分析和設計模型可以提供對什么可能出錯的深人洞察,則基于故障的測試可以以相當低的工作量花費來發現大量的錯誤。

集成測試在消息連接中查找似乎可能的故障,在此語境下,會遇到3種類型的故障:未期望的結果、錯誤的操作/消息使用、不正確的調用。為了在函數(操作)調用時確定似乎可能的故障,必須檢查操作的行為。集成測試,對象的“行為”通過其屬性被賦予的值而定義,測試應該檢查屬性以確定是否對對象行為的不同類型產生合適的值。應該注意,集成測試試圖在客戶對象而不是服務器對象中發現錯誤,用傳統的術語來說,集成測試的關注點是確定調用代碼中是否存在錯誤,而不是被調用代碼中。用調用操作作為線索,這是發現實施調用代碼的測試需求的一種方式。上一頁下一頁返回12.4面向對象軟件的測試用例設計

4.面向對象編程對測試的影響面向對象編程可能對測試有幾種方式的影響,依賴于()()P的方法。

(1)某些類型的故障變得幾乎不可能(不值得去測試)。

(2)某些類型的故障變得更加可能(值得進行測試)。

(3)出現某些新的故障類型。當調用一個操作時,可能很難確切知道執行什么代碼,即操作可能屬于很多類之一。同樣,也很難確定準確的參數類型/類,當代碼訪問參數時,可能得到一個未期望的值。可以通過考慮如下的傳統的函數調用來理解這種差異。

x=funs(Y);上一頁下一頁返回12.4面向對象軟件的測試用例設計

對傳統軟件,測試人員需要考慮所有屬于funs的行為,其他則不需考慮。在面向對象語境中,測試人員必須考慮base::func()、ofderived::func()等行為。每次funs被調用,測試人員必須考慮所有不同行為的集合,如果遵循了好的面向對象設計習慣并且限制了在超類和子類(用('十十的術語,稱為基類和派生類)間的差異,則這是較為容易的。對基類和派生類的測試方法實質上是相同的。測試面向對象的類操作類似于測試一段代碼,它設置函數參數,然后調用該函數。繼承是一種方便的生成多態操作的方式,在調用點,關心的不是繼承,而是多態。繼承確實使得對測試需求的搜索更為直接。上一頁下一頁返回12.4面向對象軟件的測試用例設計

由于面向對象系統的體系結構和構造,是否某些類型的故障更加可能,而其他類型的故障則幾乎不可能?對面向對象系統而言,回答是“是”。例如,因為面向對象操作通常是較小的,往往存在更多的集成工作和更多的集成故障的機會,集成故障變得更加可能。

5.測試用例和類層次如本帝前面所述,繼承并沒有排除對所有派生類進行全面測試的需要,事實上,它確實使測試過程變得復雜。考慮下面情形,類base包含了操作inherited和redefined,類derivcd使redefined重定義以用于局部語境中,毫無疑問,必須測試derivcd::redefined()操作,因為它表示了新的設計和新的代碼。但是,必須重測試derivcd::inherited()操作嗎?上一頁下一頁返回12.4面向對象軟件的測試用例設計

如果derivcd::inherited()調用redefined,而redefined的行為已經改變,derived:inherited()可能錯誤地處理這新行為,因此,即使其設計和代碼沒有改變,它需要被重新測試。然而,重要的是要注意,僅僅必須執行derivcd::inherited()的所有測試的一個子集。如果inherited的設計和代碼部分不依賴于redefined(即不調用它或任意間接調用‘已的代碼),則不需要在derivcd類中重測試該代碼。

base::redefined()和derivcd::redefined()是具有不同規約和實現的兩個不同的操作,它們各自具有一組從規約和實現導出的測試需求,這些測試需求探查似乎可能的故障:集成故障、條件故障、邊界故障等。但是,操作可能是相似的,它們的測試需求的集合將交迭,面向對象設計得越好,交迭就越大,僅僅需要對那些不能被base::redefined()測試滿足的derivcd::redefined()的需求來導出新測試。上一頁下一頁返回12.4面向對象軟件的測試用例設計

小結一下,base::redefined()測試被應用于類derivcd的對象,測試輸入叫能同時適合于base和derivcd類,但是,期望的結果可能在derivcd類中有所不同。

6.基于場景的測試設計基于故障的測試忽略了兩種主要的錯誤類型:①不正確的規約。②子系統間的交互。當和不正確的規約關聯的錯誤發生時,產品不做客戶希望的事情,它可能做錯誤的事情,或它可能省略了重要的功能。在任一情形下,質量(對要求的符合度)均受到影響。當一個子系統建立環境(如事件、數據流)的行為使得另一個子系統失敗時,發生和子系統交互相關聯的錯誤。

基于場景的測試關心用戶做什么而不是產品做什么。它意味著捕獲用戶必須完成的任務(通過用例),然后應用它們或它們的變體作為測試。上一頁下一頁返回12.4面向對象軟件的測試用例設計

場景揭示交互錯誤,為了達到此目標,測試用例必須比基于故障的測試更復雜和更現實。基于場景的測試往往在單個測試中處理多個子系統(用戶并不限制他們自己一次只用一個子系統)。例如,考慮對文本編輯器的基于場景的測試的設計,下面是用例。用例:確定最終草稿。背景:打印“最終”草稿、閱讀它并發現某些從屏幕上看時不明顯的惱人錯誤是常見的。該用例描述當此事發生時產生事件的序列。

(1)打印完整的文檔。

(2)在文檔中移動,修改某些頁面。

(3)當每頁被修改后,打印它。

(4)有時打印一系列頁面。上一頁下一頁返回12.4面向對象軟件的測試用例設計

該場景描述了兩件事:測試和特定的用戶需要。用戶需要是明顯的:①打印單頁的方法。②打印一組頁面的方法。當測試進行時,有需要在打印后測試編輯(以及相反)。測試人員希望發現打印功能導致了編輯功能的錯誤,即此兩個軟件功能不是合適的相互獨立的。用例:打印新復制件。背景:某人向用戶要求文檔的一份新復制件,它必須被打印。

(1)打開文檔。

(2)打印文檔。

(3)關閉文檔。測試方法也是相當明顯的,除非該文檔未在任何地方出現過,它是在早期的任務中創建的,該任務對現在的任務有影響嗎?上一頁下一頁返回12.4面向對象軟件的測試用例設計

在很多現代的編輯器中,文檔記住它們上一次被如何打印,默認情況下,它們下一次用相同的方式打印。在“確定最終草稿”場景之后,僅僅在菜單中選擇“打印”命令并在對話框中單擊“打印”按鈕,將使得上次修正的頁面再打印一次,這樣,按照編輯器,正確的場景應該如下。用例:打印新復制件。

(1)打開文檔。

(2)選擇菜單中的“打印”命令。

(3)檢查是否將打印一系列頁面,如果是,點擊以打印完整的文檔。

(4)單擊“打印”按鈕。

(5)關閉文檔。上一頁下一頁返回12.4面向對象軟件的測試用例設計

但是,這個場景指明了一個潛在的規約錯誤,編輯器沒有做用戶希望它做的事。客戶經常忽略在第(3)步中的檢查,當他們走到打印機前發現只有一頁,而他們需要100頁時,他們將是煩惱的。煩惱的客戶會指出這一規約錯誤。

測試用例的設計者可能在測試設計中忽略這種依賴,但是,有可能在測試中問題會出現,測試員則將必須克服可能的反應,“這就是它工作的方式”。

7.測試表層結構和深層結構表層結構指面向對象程序的外部可觀察的結構,即對終端用戶立即可見的結構。不是處理函數,而是很多面向對象系統的用戶可能被給定一些以某種方式操縱的對象。但是不管接口是什么,測試仍然基于用戶任務進行。捕獲這些任務涉及理解、觀察以及和代表性用戶(以及很多值得考慮的非代表性用戶)的交談。上一頁下一頁返回12.4面向對象軟件的測試用例設計

在細節上一定存在某些差異。例如,在傳統的具有面向命令的界面的系統中,用戶可能使用所有命令的列表作為檢查表。如果不存在執行某命令的測試場景,測試可能忽略某些用戶任務(或具有無用命令的界面)。在基于對象的界面中,測試人員可能使用所有的對象列表作為檢查表。

當設計者以一種新的或非傳統的方式來看待系統時,則可以得到最好的測試。例如,如果系統或產品具有基于命令的界面,則當測試用例設計者假設操作是獨立于對象的,將可以得到更徹底的測試。提出這樣的問題:“當使用打印機工作時,用戶有可能希望使用該操作(它僅應用于掃描儀對象)嗎?”不管界面風格是什么,針對表層結構的測試用例設計應該同時使用對象和操作作為導向被忽視任務的線索。

上一頁下一頁返回12.4面向對象軟件的測試用例設計

深層結構指面向對象程序的內部技術細節,即通過檢查設計和/或代碼而理解的結構。深層結構測試被設計用以測試作為面向對象系統的子系統和對象設計的一部分而建立的依賴、行為和通信機制。

分析和設計模型被用作深層結構測試的基礎。例如,對象關系圖或子系統協作圖描述了在對象和子系統間的可能對外不可見的協作。那么測試用例設計者會問:“我們已經捕獲了某些測試任務,它測試在對象關系圖或子系統協作圖中記錄的協作?如果沒有,為什么?”

類層次的設計表示提供了對繼承結構的誤人洞察,繼承結構被用在基于故障的測試中。考慮如下情形:一個命名為caller的操作只有一個參數,并且該參數是到某基類的引用。當caller被傳遞給派生類時將發生什么事情?可能影響caller的行為有什么差異?對這些問題的回答可能導向特殊測試的設計。上一頁返回12.5面向對象的測試過程

傳統的面向過程分析是一個功能分解的過程,是把一個系統看成可以分解的功能的集合。這種傳統的功能分解分析法的著眼點在于一個系統需要什么樣的信息處理方法和過程,以過程的抽象來對待系統的需要。而面向對象分析(OOA)是“把E-R圖和語義網絡模型,即信息造型中的概念,與面向對象程序設計語言中的重要概念結合在一起而形成的分析方法”,最后通常是得到問題空間的圖表的形式描述。

OOA直接映射問題空間,全面地將問題空間中實現功能的現實抽象化。將問題空間中的實例抽象為對象(不同于C++中的對象概念),用對象的結構反映問題空間的復雜實例和復雜關系,用屬性和服務表示實例的特性和行為。對一個系統而言,與傳統分析方法產生的結果相反,行為是相對穩定的,結構是相對不穩定的,這更充分反映了現實下一頁返回12.5面向對象的測試過程

的特性。OOA的結果是為后面階段類的選定和實現,類層次結構的組織和實現提供平臺。因此,OOA對問題空間分析抽象的不完整,最終會影響軟件的功能實現,導致軟件開發后期大量可避免的修補工作;而一些冗余的對象或結構會影響類的選定、程序的整體結構或增加程序員不必要的工作量。因此,對OOA的測試重點在其完整性和冗余性。

盡管OOA的測試是一個不可分割的系統過程,為敘述的方便,鑒于之前章節提到的OOA實現步驟,對OOA階段的測試劃分為以下5個方面。

(1)對認定的對象的測試。

(2)對認定的結構的測試。

(3)對認定的主題的測試。

上一頁下一頁返回12.5面向對象的測試過程

(4)對定義的屬性和實例關聯的測試。

(5)對定義的服務和消息關聯的測試。

假設有一個車輛管理系統的面向對象分析結果,對象、結構、主題等在OOA結果中的位置如圖12.1所示。

OOA中認定的對象是對問題空間中的結構、其他系統、設備、被記憶的事件、系統涉及的人員等實際實例的抽象。對它的測試可以從如下方面考慮。

(1)認定的對象是否全面,是否問題空間中所有涉及的實例都反映在認定的抽象對象中。

(2)認定的對象是否具有多個屬性。只有一個屬性的對象通常應看成其他對象的屬性,而不是抽象為獨立的對象。

上一頁下一頁返回12.5面向對象的測試過程

(3)對認定為同一對象的實例是否有共同的、區別于其他實例的共同屬性。

(4)對認定為同一對象的實例是否提供或需要相同的服務,如果服務隨著不同的實例而變化,認定的對象就需要分解或利用繼承性來分類表示。

(5)如果系統沒有必要始終保持對象代表的實例的信息,提供或者得到關于它的服務,認定的對象也無必要。

(6)認定的對象的名稱應該盡量準確、適用。認定的結構指的是多種對象的組織方式,用來反映問題空間中的復雜實例和復雜關系。認定的結構分為兩種:分類結構和組裝結構。分上一頁下一頁返回12.5面向對象的測試過程

類結構體現了問題空間中實例的一般與特殊的關系,組裝結構體現了問題空間中實例整體與局部的關系。對認定的結構的測試包含以下內容。

(1)對認定的分類結構的測試可從如下方面著手。

@對于結構中的一種對象,尤其是處于高層的對象,是否在問題空間中含有不同于下一層對象的特殊可能性,即是否能派生出下一層對象。⑥對于結構中的一種對象,尤其是處于同一低層的對象,是否能抽象出在現實中有意義的更一般的上層對象。

@對所有認定的對象,是否能在問題空間內向上層抽象出在現實中有意義的對象,高層的對象的特性是否完全體現下層的共性。④低層的對象是否有高層特性基礎上的特殊性。上一頁下一頁返回12.5面向對象的測試過程

(2)對認定的組裝結構的測試從如下方面入手。

@整體(對象)和部件(對象)的組裝關系是否符合現實的關系。⑥整體(對象)的部件(對象)是否在考慮的問題空間中有實際應用。

@整體(對象)中是否遺漏了反映在問題空間中有用的部件(對象)。⑧部件(對象)是否能夠在問題空間中組裝新的有現實意義的整體(對象)。主題是在對象和結構的基礎上更高一層的抽象,是為了提供面向對象分析結果的可見性,如同文章對各部分內容的概要。對主題層的測試應該考慮以下方面。

上一頁下一頁返回12.5面向對象的測試過程

(1)如果主題個數超過7個,就要求對有較密切屬性和服務的主題進行歸并。

(2)主題所反映的一組對象和結構是否具有相同和相近的屬性和服務。

(3)認定的主題是否是對象和結構更高層的抽象,是否便于理解(OOA結果的概貌(尤其是對非技術人員的(OOA結果讀者)。

(4)主題間的消息聯系(抽象)是否代表了主題所反映的對象和結構之間的所有關聯。屬性是用來描述對象或結構所反映的實例的特性。而實例關聯是反映實例集合間的映射關系。對屬性和實例關聯的測試從如下方面考慮。上一頁下一頁返回12.5面向對象的測試過程

(1)定義的屬性是否對相應的對象和分類結構的每個現實實例都適用。(2)定義的屬性在現實世界是否與這種實例關系密切。(3)定義的屬性在問題空間是否與這種實例關系密切。(4)定義的屬性是否能夠不依賴于其他屬性被獨立理解。(5)定義的屬性在分類結構中的位置是否恰當,低層對象的共有屬性是否在上層對象屬性體現。

(6)在問題空間中每個對象的屬性是否定義完整。

(7)定義的實例關聯是否符合現實。

(8)在問題空間中實例關聯是否定義完整,特別需要注意1-多和多一多的實例關聯。上一頁下一頁返回12.5面向對象的測試過程

定義的服務,就是定義的每一種對象和結構在問題空間所要求的行為。由于問題空間中實例間必要的通信,在OOD中相應需要定義消息關聯。對定義的服務和消息關聯的測試從如下方面進行。

(1)對象和結構在問題空間的不同狀態是否定義了相應的服務。

(2)對象或結構所需要的服務是否都定義了相應的消息關聯。

(3)定義的消息關聯所指引的服務提供是否正確。

(4)沿著消息關聯執行的線程是否合理,是否符合現實過程。

(5)定義的服務是否重復,是否定義了能夠得到的服務。上一頁返回12.6在類級別上的測試方法

軟件測試從“小型”測試開始,慢慢進展到“大型”測試。對面向對象系統的小型測試著重于單個類和類封裝的方法。隨機測試和劃分是在面向對象測試中測試類的方法。

1.對面向對象類的隨機測試通常的結構化的設計方法,用的“是面向作業的設計方法,它把系統分解以后,提出一組作業,這些作業是以過程實現系統的基礎構造,把問題域的分析轉化為求解域的設計,分析的結果是設計階段的輸入”。而面向對象設計(OOD)采用“造型的觀點”,以OOA為基礎歸納出類,并建立類結構或進一步構造成類庫,實現分析結果對問題空間的抽象.OOD歸納的類,可以是對象簡單的延續,可以是不同對象的相下一頁返回12.6在類級別上的測試方法

同或相似的服務。由此可見,OOD不是在OOA上的另一思維方式的大動干戈,而是OOA的進一步細化和更高層的抽象。所以,OOD與OOA的界限通常是難以嚴格區分的。OOD確定類和類結構不僅是滿足當前需求分析的要求,更重要的是通過重新組合或加以適當的補充,能方便實現功能的重用和擴增,以不斷適應用戶的要求。因此,對OOD的測試,本文建議針對功能的實現和重用以及對OOA結果的拓展,從如下3方面考慮。

1)對認定的類的測試

OOD認定的類可以是OOA中認定的對象,也可以是對象所需要的服務的抽象,對象所具有的屬性的抽象。認定的類原則上應該盡量基礎性,這樣才便于維護和重用。測試認寧的舉的一必準則如下上一頁下一頁返回12.6在類級別上的測試方法

(1)是否涵蓋了OOA中所有認定的對象。(2)是否能體現OOA中定義的屬性。(3)是否能實現OOA中定義的服務。(4)是否對應著一個含義明確的數據抽象。(5)是否盡可能少地依賴其他類。(6)類中的方法(C++類的成員函數)是否單用途。

2)對構造的類層次結構的測試為了能充分發揮面向對象的繼承共享特性,OOD的類層次結構,通常基于OOA中產生的分類結構的原則來組織,著重體現父類和子類間一般性和特殊性。在當前的問題空間,對類層次結構的主要要求是能在解空間構造實現全部功能的結構框架。為此,測試如下方面。上一頁下一頁返回12.6在類級別上的測試方法

(1)類層次結構是否涵蓋了所有定義的類。(2)是否能體現OOA中所定義的實例關聯。(3)是否能實現OOA中所定義的消息關聯。(4)子類是否具有父類沒有的新特性。(5)子類間的共同特性是否完全在父類中得以體現。3)對類庫支持的測試對類庫的支持雖然也屬于類層次結構的組織問題,但其強調的重點是再次軟件開發的重用。由于它并不直接影響當前軟件的開發和功能實現,因此,將其單獨提出來測試,也可作為對高質量類層次結構的評估。測試點如下。上一頁下一頁返回12.6在類級別上的測試方法

(1)一組子類中關于某種含義相同或基本相同的操作,是否有相同的接口(包括名字和參數表)。

(2)類中方法(C++---類的成員函數)功能是否較單純,相應的代碼行是否較少(建議為不超過30行)。

(3)類的層次結構是否是深度大、寬度小。為了提供時這些方法的簡略性說明,考慮一個銀行應用,其中;account類有下列操作:open,setup,deposit,withdrawbalance,summarize,crcditI_imit和close,每一個操作均可應用于;account,但是,該問題的本質包含了一些限制(如賬號必須在其他操作可應用前被打開,在所有操作完成后才關閉)。即使有了這些限制,也存在操作的很多排列。一個;account實例的最小的行為生命歷史包括下面操作:上一頁下一頁返回12.6在類級別上的測試方法

open·setup·deposit·withdraw·close這表示了對;account的最小測試序列,然而,在下面序列中可能發生大量的其他行為:Open·setup·deposit·[deposit|withdraw|balance|summartzc|crcditLimit]n·withdraw.close一系列不同的操作序列可以隨機產生,例如:測試用例#r1open·setup·deposit·deposit·balance·summarize·withdraw·close測試用例#r2open·setup·deposit·withdraw·deposit·balance·crcditLimit·withdraw·close執行這些和其他的隨機順序測試以測試不同的類實例生命歷史。上一頁下一頁返回12.6在類級別上的測試方法

2.在類級別上的劃分測試采用劃分測試可以來減少測試類所需的測試用例的數量。傳統軟件的等價劃分基本相同的方式輸入和輸出被分類,測試用例被設計以處理每個類別。但是,劃分類別是如何導出的呢?

基于狀態的劃分是根據類操作改變類的狀態的能力來劃分類操作的。再次考慮;account類,狀態操作包括(lcposit和withdraw,而非狀態操作包括balance,summarize和crcdit-Limit。測試被以這樣一種方式來設計:分別獨立測試改變狀態的操作和不改變狀態的操作,因此:測試用例#p1:open·setup·deposit·deposit·withdraw·withdraw·close測試用例#p2:open·setup·deposit·summarize·crcditLimit·withdraw·close上一頁下一頁返回12.6在類級別上的測試方法

測試用例#p1改變狀態,而測試用例井p2測試不改變狀態的操作(除了那些在最小序列中的操作)。基于屬性的劃分是根據操作使用的屬性來劃分類操作。對;account類,用屬性balance和creditlimit來定義劃分,操作被分為3個類別:①使用creditlimit的操作。②修改creditlimit的操作。③不使用或不修改creditlimit的操作。然后對每個劃分設

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論