軟件架構之測評方法
- 第 11 章:測試評審方法
- 11.1 測試方法
- 11.1.1 軟件測試階段
- 11.1.2 白盒測試和黑盒測試
- 11.1.3 缺陷的分類和級別
- 11.1.4 調試
- 11.2 評審方法
- 11.3 驗證與確認
- 11.4 測試自動化
- 11.5 面向對象的測試
第 11 章:測試評審方法
軟件測試與評審是軟件質量保證的主要手段之一,也是在將軟件交付給客戶之前所必須完成的步驟。目前,軟件的正確性證明尚未得到根本的解決,軟件測試與評審仍是發現軟件錯誤(缺陷)的主要手段。
本章重點要求讀者掌握測試方法、評審方法、驗證與確認、測試自動化、面向對象的測試等 5 個方面的知識。
11.1 測試方法
在介紹軟件測試之前,首先應該明確“錯誤”(error)和“缺陷”(fault)的概念。根據IEEE 的定義,“錯誤”主要針對軟件開發過程,“缺陷”主要針對軟件產品。軟件開發人員在軟件開發過程(主要是分析、設計和編碼過程)中所出現的“錯誤”是導致軟件產品“缺陷”的原因,反過來說,“缺陷”是“錯誤”的結果和表現形式。
軟件測試的目的就是在軟件投入生產性運行之前,盡可能多地發現軟件產品(主要是指程序)中的錯誤(缺陷)。 為了發現軟件中的錯誤(缺陷),應竭力設計能暴露錯誤(缺陷)的測試用例。
測試用例是由測試數據和預期結果構成的。一個好的測試用例是極有可能發現至今為止尚未發現的錯誤(缺陷)的測試用例。一次成功的測試是發現了至今為止尚未發現的錯誤(缺陷)的測試。
高效的測試是指用少量的測試用例,發現被測軟件盡可能多的錯誤(缺陷)。軟件測試所追求的目標就是以盡可能少的時間和人力發現軟件產品中盡可能多的錯誤(缺陷)
11.1.1 軟件測試階段
從測試階段上分,軟件測試通常可分為單元測試、集成測試和系統測試。
1.單元測試
單元測試(unit testing),也稱模塊測試,通常可放在編程階段,由程序員對自己編寫的模塊自行測試,檢查模塊是否實現了詳細設計說明書中規定的功能和算法。單元測試主要發現編程和詳細設計中產生的錯誤,單元測試計劃應該在詳細設計階段制定。
單元測試期間著重從以下幾個方面對模塊進行測試:模塊接口、局部數據結構、重要的執行通路、出錯處理通路和邊界條件等。 測試一個模塊時需要為該模塊編寫一個驅動模塊和若干個樁(stub)模塊。驅動模塊用來調用被測模塊,它接收測試者提供的測試數據,并把這些數據傳送給被測模塊,然后從被測模塊接收測試結果,并以某種可以看見的方式(例如顯示或打印)將測試結果返回給測試者。樁模塊用來模擬被測模塊所調用的子模塊,它接受被測模塊的調用,檢驗調用參數,并以盡可能簡單的操作模擬被調用的子程序模塊功能,把結果送回被測模塊。頂層模塊測試時不需要驅動模塊,底層模塊測試時不需要樁模塊。
模塊的內聚程度高可以簡化單元測試過程。如果每個模塊只完成一種功能,則需要的測試方案數目將明顯減少,模塊中的錯誤也更容易預測和發現。
2.集成測試
集成測試(integration testing),也稱組裝測試,它是對由各模塊組裝而成的程序進行測試,主要目標是發現模塊間的接口和通信問題。例如,數據穿過接口可能丟失,一個模塊對另一個模塊可能由于疏忽而造成有害影響,把子功能組合起來可能不產生預期的主功能,個別看來是可以接受的誤差可能積累到不能接受的程度,全程數據結構可能有問題等。集成測試主要發現設計階段產生的錯誤,集成測試計劃應該在概要設計階段制訂。
集成的方式可分為非漸增式和漸增式。
- 非漸增式集成是先測試所有的模塊,然后一下子把所有這些模塊集成到一起,并把龐大的程序作為一個整體來測試。這種測試方法的出發點是可以“一步到位”,但測試者面對眾多的錯誤現象,往往難以分清哪些是“真正的”錯誤,哪些是由其他錯誤引起的“假性錯誤”,診斷定位和改正錯誤也十分困難。非漸增式集成只適合一些非常小的軟件。
- 漸增式集成是將單元測試和集成測試合并到一起,它根據模塊結構圖,按某種次序選一個尚未測試的模塊,把它同已經測試好的模塊組合在一起進行測試,每次增加一個模塊,直到所有模塊被集成在程序中。這種測試方法比較容易定位和改正錯誤,目前在進行集成測試時已普遍采用漸增式集成。
漸增式集成又可分為自頂向下集成和自底向上集成。自頂向下集成先測試上層模塊,再測試下層模塊。由于測試下層模塊時它的上層模塊已測試過,所以不必另外編寫驅動模塊。
自底向上集成先測試下層模塊,再測試上層模塊。同樣,由于測試上層模塊時它的下層模塊已測試過,所以不必另外編寫樁模塊。這兩種集成方法各有利弊,一種方法的優點恰好對應于另一種方法的缺點,實際測試時可根據軟件特點及進度安排靈活選用最適當的方法,也可將兩種方法混合使用。
3.系統測試
系統測試是軟件測試中的最后的、最完整的測試,它是在單元測試和集成測試的基礎上進行的,它從全局來考察軟件系統的功能和性能要求。系統測試計劃應該在需求分析階段制訂。 通常,系統測試包括確認測試和驗收測試。
確認測試,主要依據軟件需求說明書檢查軟件的功能、性能及其他特征是否與用戶的需求一致。軟件配置復查是確認測試的另一項重要內容。復查的目的是保證軟件配置的所有成分都已齊全,質量符合要求,文檔與程序完全一致,具有完成軟件維護所必需的細節。 如果一個軟件是為某個客戶定制的,最后還要由該客戶來實施驗收測試,以便確認其所有需求是否都已得到滿足。由于軟件系統的復雜性,在實際工作中,驗收測試可能會持續到用戶實際使用該軟件之后的相當長的一段時間。 如果一個軟件是作為產品被許多客戶使用的,不可能也沒必要由每個客戶進行驗收測試。
絕大多數軟件開發商都使用被稱為 (Alpha)測試和 (Beta)測試的過程,來發現那些看起來只有最終用戶才能發現的錯誤。
a 測試由用戶在開發者的場所進行,并且在開發者的指導下進行測試。開發者負責記錄發現的錯誤和使用中遇到的問題。也就是說, 測試是在“受控的”環境中進行的。
b 測試是在一個或多個用戶的現場由該軟件的最終用戶實施的,開發者通常不在現場,用戶負責記錄發現的錯誤和使用中遇到的問題并把這些問題報告給開發者。也就是說,測試是在“不受控的”環境中進行的。經過系統測試之后的軟件通常就可以交付使用了。
11.1.2 白盒測試和黑盒測試
從測試方法上分,軟件測試可分為白盒測試和黑盒測試。
1.白盒測試
白盒測試,又稱結構測試,主要用于單元測試階段。它的前提是可以把程序看成裝在一個透明的白箱子里,測試者完全知道程序的結構和處理算法。這種方法按照程序內部邏輯設計測試用例,檢測程序中的主要執行通路是否都能按預定要求正常工作。
白盒測試根據軟件的內部邏輯設計測試用例,常用的技術是邏輯覆蓋,即考察用測試數據運行被測程序時對程序邏輯的覆蓋程度。主要的覆蓋標準有 6 種:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、組合條件覆蓋和路徑覆蓋。
(1)語句覆蓋。語句覆蓋是指選擇足夠多的測試用例,使得運行這些測試用例時,被測程序的每個語句至少執行一次。很顯然,語句覆蓋是一種很弱的覆蓋標準。
(2)判定覆蓋。判定覆蓋又稱分支覆蓋,它的含義是,不僅每個語句至少執行一次,而且每個判定的每種可能的結果(分支)都至少執行一次。判定覆蓋比語句覆蓋強,但對程序邏輯的覆蓋程度仍然不高。
(3)條件覆蓋。條件覆蓋的含義是,不僅每個語句至少執行一次,而且使判定表達式中的每個條件都取得各種可能的結果。條件覆蓋不一定包含判定覆蓋,判定覆蓋也不一定包含條件覆蓋。
(4)判定/條件覆蓋。同時滿足判定覆蓋和條件覆蓋的邏輯覆蓋稱為判定/條件覆蓋。它的含義是,選取足夠的測試用例,使得判定表達式中每個條件的所有可能結果至少出現一次,而且每個判定本身的所有可能結果也至少出現一次。
(5)條件組合覆蓋。條件組合覆蓋的含義是,選取足夠的測試用例,使得每個判定表達式中條件結果的所有可能組合至少出現一次。顯然,滿足條件組合覆蓋的測試用例,也一定滿足判定/條件覆蓋。因此,條件組合覆蓋是上述 5 種覆蓋標準中最強的一種。然而,條件組合覆蓋還不能保證程序中所有可能的路徑都至少經過一次。
(6)路徑覆蓋。路徑覆蓋的含義是,選取足夠的測試用例,使得程序的每條可能執行到的路徑都至少經過一次(如果程序中有環路,則要求每條環路路徑至少經過一次)。路徑覆蓋實際上考慮了程序中各種判定結果的所有可能組合,因此是一種較強的覆蓋標準。但路徑覆蓋并未考慮判定中的條件結果的組合,并不能代替條件覆蓋和條件組合覆蓋。
2.黑盒測試
黑盒測試,又稱功能測試,主要用于集成測試和確認測試階段。它把軟件看作一個不透明的黑箱子,完全不考慮(或不了解)軟件的內部結構和處理算法,它只檢查軟件功能是否能按照軟件需求說明書的要求正常使用,軟件是否能適當地接收輸入數據并產生正確的輸出信息,軟件運行過程中能否保持外部信息(例如文件和數據庫)的完整性等。黑盒測試根據軟件需求說明書所規定的功能來設計測試用例,它不考慮軟件的內部結構
和處理算法。
常用的黑盒測試技術包括等價類劃分、邊值分析、錯誤推測和因果圖等。
(1)等價類劃分。在設計測試用例時,等價類劃分是用得最多的一種黑盒測試方法。
所謂等價類就是某個輸入域的集合,對于一個等價類中的輸入值來說,它們揭示程序中錯誤的作用是等效的。也就是說,如果等價類中的一個輸入數據能檢測出一個錯誤,那么等價類中的其他輸入數據也能檢測出同一個錯誤;反之,如果等價類中的一個輸入數據不能檢測出某個錯誤,那么等價類中的其他輸入數據也不能檢測出這一錯誤(除非這個等價類的某個子集還屬于另一等價類)。
如果一個等價類內的數據是符合(軟件需求說明書)要求的、合理的數據,則稱這個等價類為有效等價類。有效等價類主要用來檢驗軟件是否實現了軟件需求說明書中規定的功能。
如果一個等價類內的數據是不符合(軟件需求說明書)要求的、不合理或非法的數據,則稱這個等價類為無效等價類。無效等價類主要用來檢驗軟件的容錯性。黑盒測試中,利用等價類劃分方法設計測試用例的步驟是:
① 根據軟件的功能說明,對每一個輸入條件確定若干個有效等價類和若干個無效等價類,并為每個有效等價類和無效等價類編號。
② 設計一個測試用例,使其覆蓋盡可能多的尚未被覆蓋的有效等價類。重復這一步,直至所有的有效等價類均被覆蓋。
③ 設計一個測試用例,使其覆蓋一個尚未被覆蓋的無效等價類。重復這一步,直至所有的無效等價類均被覆蓋。
無效等價類是用來測試非正常的輸入數據的,因此每個無效等價類都有可能查出軟件中的錯誤,所以要為每個無效等價類設計一個測試用例。
(2)邊值分析。經驗表明,軟件在處理邊界情況時最容易出錯。設計一些測試用例,使軟件恰好運行在邊界附近,暴露出軟件錯誤的可能性會更大一些。
通常,每一個等價類的邊界,都應該著重測試,選取的測試數據應該恰好等于、稍小于或稍大于邊界值。 將等價類劃分法和邊值分析法結合使用,更有可能發現軟件中的錯誤。
(3)錯誤推測。使用等價類劃分和邊值分析技術,有助于設計出具有代表性的、容易暴露軟件錯誤的測試方案。但是,不同類型不同特定的軟件通常又有一些特殊的容易出錯的地方。錯誤推測法主要依靠測試人員的經驗和直覺,從各種可能的測試方案中選一些最可能引起程序出錯的方案。
(4)因果圖。因果圖法是根據輸入條件與輸出結果之間的因果關系來設計測試用例的,它首先檢查輸入條件的各種組合情況,并找出輸出結果對輸入條件的依賴關系,然后為每種輸出條件的組合設計測試用例。
11.1.3 缺陷的分類和級別
根據 IEEE 標準和 Paul C.Jorgensen 的教科書,軟件測試中所發現的錯誤(缺陷)主要包括以下幾類:
(1)輸入/輸出錯誤。包括不接收正確的輸入、接收不正確的輸入、描述有錯或遺漏、參數有錯或遺漏、輸出結果有誤、輸出格式有誤、輸出時間有誤、結果不一致、遺漏結果、不合邏輯的結果、拼寫/語法錯誤、修飾詞錯誤。
(2)邏輯錯誤。包括遺漏情況、重復情況、極端條件出錯、解釋有誤、遺漏條件、外部條件有錯、錯誤變量的測試、不正確的循環迭代、錯誤的操作符。
(3)計算錯誤。包括不正確的算法、遺漏計算、不正確的操作數、不正確的操作、括號錯誤、精度不夠錯誤的內置函數。
(4)接口錯誤。包括不正確的中斷處理、I/O 時序有錯、調用了錯誤的過程、調用了不存在的過程、參數不匹配、不兼容的類型、過量的包含。
(5)數據錯誤。包括不正確的初始化、不正確的存儲/訪問、錯誤的標識/索引值、不正確的打包/拆包、使用了錯誤的變量、錯誤的數據引用、縮放數據范圍或單位錯誤、不正確的數據維數、不正確的下標、不正確的類型、不正確的數據范圍、數據超出限制、數據溢出、不一致的數據。根據錯誤(缺陷)后果的嚴重程度,Beizer 將錯誤(缺陷)分為 10 級:
(1)輕微(例如,界面文字有個別的錯別字,但不影響理解)。
(2)中等(例如,界面文字錯誤可能誤導操作者)。
(3)使人不悅(例如,數字串被斷開)。
(4)影響使用(例如,有些交易沒有處理)。
(5)嚴重(例如,丟失交易)。
(6)非常嚴重(例如,不正確的交易處理)。
(7)極為嚴重(例如,經常出現不正確的交易處理)。
(8)無法容忍(例如,數據庫遭到破壞)。
(9)災難性(例如,系統無法工作)。
(10)傳染性(例如,可導致其他系統無法工作)
11.1.4 調試
調試又稱為排錯,調試與成功的測試形影相隨。測試成功的標志是發現了錯誤。根據錯誤跡象確定錯誤的原因和準確位置并加以改正,主要依靠排錯技術。
調試是一個相當艱苦的過程,究其原因除了開發人員心理方面的障礙外,還因為隱藏在程序中的錯誤具有下列特殊的性質:
(1)錯誤的外部征兆遠離引起錯誤的內部原因,對于高度耦合的程序結構此類現象更為嚴重。
(2)糾正一個錯誤造成了另一錯誤現象(暫時)的消失。
(3)某些錯誤征兆只是假象。
(4)因操作人員一時疏忽造成的某些錯誤征兆不易追蹤。
(5)錯誤是由于分時而不是程序引起的。
(6)輸入條件難以精確地再構造(例如,某些實時應用的輸入次序不確定)。
(7)錯誤征兆時有時無,此現象對嵌入式系統尤其普遍。
(8)錯誤是由于把任務分布在若干臺不同處理機上運行而造成的。
在軟件排錯過程中,可能遇到大大小小、形形色色的問題,隨著問題的增多,排錯人員的壓力也隨之增大,過分的緊張致使開發人員在排除一個問題的同時又引入更多的新問題。
盡管排錯不是一門好學的技術,但還是有若干行之有效的方法和策略的,常用的排錯策略分為三類:
(1)原始類。原始類排錯方法是最常用也是最低效的方法,只有在萬般無奈的情況下才使用它,主要思想是“通過計算機找錯”。例如輸出存儲器、寄存器的內容,在程序安排若干輸出語句等,憑借大量的現場信息,從中找到出錯誤的線索。雖然最終也能成功,但難免要耗費大量的時間和精力。
(2)回溯類。回溯法能成功地用于程序的排錯。方法是從出現錯誤征兆處開始,人工地沿控制流程往回追蹤,直至發現出錯的根源,不幸的是程序變大后,可能的回溯路線顯著增加,以致人工進行完全回溯可望而不可即。
(3)排除類。排除法基于歸納和演繹原理,采用“分治”的概念,首先分析與錯誤出現有關的所有數據,假想一個錯誤原因,用這些數據證明或反駁它;或者一次列出所有可能的原因,通過測試一一排除。只要某次測試結果說明某種假設已呈現端倪,則立即精化數據,乘勝追擊。
11.2 評審方法
根據 IEEE 1028 的定義,評審是對軟件元素或者項目狀態的一種評估手段,以確定其是否與計劃的結果保持一致,并使其得到改進。狹義的“軟件評審”通常指軟件文檔和源程序的評審。廣義的“軟件評審”還包括與軟件測試相結合的評審及管理評審。軟件評審包括軟件需求評審、概要設計評審、詳細設計評審、軟件驗證和確認評審、功能檢查、物理檢查、綜合檢查和管理評審。
(1)軟件需求評審。在軟件需求分析結束后必須進行軟件需求評審( software requirements review),以確保在軟件需求說明書中所規定的各項需求的合適性。
(2)概要設計評審。在軟件概要設計結束后必須進行概要設計評審(preliminary design review),以評價軟件設計說明書中所描述的軟件概要設計在總體結構、外部接口、主要部件功能分配、全局數據結構以各主要部件之間的接口等方面的合適性。
(3)詳細設計評審。在軟件詳細設計結束后必須進行詳細設計評審(detailed design review),以評價軟件設計說明書中所描述的軟件詳細設計在每一個基本部件的功能、算法和過程描述等方面的合適性。
(4)軟件驗證和確認評審。在軟件驗證與確認計劃完成后必須進行軟件驗證與確認評審(software verification and validation review),以評價軟件驗證與確認計劃中所規定的驗證與確認方法的合適性與完整性。
(5)功能檢查。在軟件釋放前,要對軟件進行功能檢查(functional audit),以驗證所開發的軟件已經滿足在軟件需求說明書中規定的所有需求。
(6)物理檢查。在軟件驗收前,要對軟件進行物理檢查(physical audit),以驗證程序和文檔已經一致并已做好了交付的準備。
(7)綜合檢查。在軟件驗收時,要允許用戶或用戶所委托的專家對所要驗收的軟件進行設計抽樣的綜合檢查(comprehensive audit),以驗證代碼和設計文檔的一致性、接口規格說明的一致性(硬件和軟件)、設計實現和功能需求的一致性、功能需求和測試描述的一致性。
(8)管理評審。要對計劃的執行情況定期(或按階段)進行管理評審(management reviews),這些評審必須由獨立于被評審單位的機構或授權的第三方主持進行。在評審過程中,以下幾點值得注意:
(1)不應以測試代替評審。許多缺陷是在早期階段引入的,缺陷發現得越晚,糾正費用越高。而且每個進入下一步驟的缺陷都可能引起下一步驟中的多個缺陷,導致消除成本的劇增。早期階段可以進行評審,但是無法進行測試,評審的目的就是減少泄漏到測試階段的缺陷。評審可能會花很多時間,但在測試中節省了時間。而且,測試也不能發現某些特定類型的缺陷(例如違犯編程規范)。
(2)評審人員應關注產品而不應評論開發人員。評審的主要目的是發現產品中的問題,而不是根據產品來評價開發人員的水平。但是往往會出現把產品質量和開發人員水平聯系起來的事情,于是評審變了味,變成了“批斗大會”,極大地打擊了開發人員的自尊心,以至于嚴重地影響了評審的效果。
(3)評審人員應關注于實質性問題。評審中經常會出現這樣的現象,評審人員過多地關注于一些非實質性的問題,例如,文檔的格式、措詞,而不是產品的設計。出現這種情況,可能的原因有:沒有選擇合適的人參加評審,評審人員對評審對象沒有足夠的了解,無法發現深層次的問題。
(4)評審會議不應變為問題解決方案討論會。評審會議主要的目的是發現問題,而不是解決問題,問題的解決是評審會議之后需要做的事情。但是,由于開發人員對技術的追求,評審會議往往變成了問題研討會,大量地占用了評審會議的時間,導致大量評審內容被忽略,留下無數的隱患。
(5)評審應被安排進入項目計劃。參與評審需要投入大量的時間和精力,應該被安排進入項目計劃中。但在現實中,評審往往變成了臨時安排的工作。如此一來,出現評審人員對評審對象不了解的情況也就不足為奇了。
(6)評審參與者應了解整個評審過程。如果評審參與者不了解整個的評審過程,就會有一種自然的抗拒情緒,因為大家看不到做這件事情的效果,感覺很迷茫,這樣會嚴重地影響大家參與評審的積極性。
(7)評審人員事先應對評審材料充分了解。任何一份評審材料都是他人智慧和心血的結晶,需要花足夠的時間去了解、熟悉和思考。只有這樣,才能在評審會議上發現有價值的深層次問題。在很多的評審中,評審人員因為各種的原因,在評審會議之前對評審材料沒有足夠的了解,于是出現了評審會議變成了技術報告的怪現象。
(8)應重視評審的組織工作。在組織評審的過程中,很多人不太注意細節。例如,會議時間的設定,會議的通知,會議場所的選擇,會場環境的布置,會議設施的提供,會議上氣氛的調節和控制等,而實際上這樣的細節會大大影響評審會議的效果。
11.3 驗證與確認
驗證與確認都是確定軟件產品是否滿足其預期要求和條件的過程。驗證可適用于分析、設計、編碼、測試和評審等眾多的過程,而確認通常用于驗收過程。
1.驗證
軟件項目的驗證一般應包括合同驗證、過程驗證、需求驗證、設計驗證、編碼驗證、集成驗證和文檔驗證。
(1)合同驗證。應根據下列準則驗證合同:
- 供方具有滿足需求的能力。
- 需求是一致的并覆蓋了用戶的需要。
- 為處理需求變更和升級問題規定了適當的規程。
- 規定了各方之間的接口及其合作規程與范圍,包括所有權、許可權、版權和保密要求。
- 按照需求規定了驗收準則和規程。
(2)過程驗證。應根據下列準則驗證過程:
- 項目是適當的、及時的。
- 為項目選擇的過程是適當的并滿足合同要求的。
- 用于項目過程的標準、規程和環境是適當的。
- 根據合同要求為項目配備了經過培訓的人員。
(3)需求驗證。應根據下列準則驗證需求:
- 需求是明確的、一致的、無歧義的。
- 需求是可行的。
- 需求是可測試的。
(4)設計驗證。應根據下列準則驗證設計:
- 設計是正確的,是可以實現需求的。
- 可以從需求導出設計,可以從設計追蹤需求。
(5)編碼驗證。應根據下列準則驗證編碼:
- 編碼是正確的,可以實現設計和需求。
- 可以從設計導出編碼,可以從編碼追蹤設計。
(6)集成驗證。應根據下列準則驗證集成:
每一個軟件項的軟件部件和軟件單元已完整、正確地集成到軟件項中。系統的硬件項、軟件項和人工操作已完整、正確地集成到系統中。
(7)文檔驗證。應根據下列準則驗證文檔:文檔是充分的、完備的、一致的。文檔制訂是及時的。文檔配置管理遵循了規定的規程。
2.確認
如果項目需要開展確認工作,應建立一個確認過程,以確認軟件產品滿足其預期用途。確認可以是組織內部的,也可以由獨立的第三方實施。
一般來講,確認過程應包括下列任務:
(1)編寫測試需求、測試用例和測試規程。
(2)確保這些測試需求、測試用例和測試規程可以反映軟件產品的預期用途。
(3)執行測試。
(4)確認軟件產品滿足其預期用途。
11.4 測試自動化
軟件測試的工作量很大,但測試卻極有可能應用計算機進行相當一部分自動化的工作,原因是測試的許多操作是重復性的、非智力創造性的、需要細致注意力的工作,而計算機就最適合于代替人類去完成這些任務。測試自動化會對整個開發工作的質量、成本和周期帶來非常明顯的效果。 一些適于考慮進行自動化的測試工作為:
(1)測試用例的生成(包括測試輸入、標準輸出、測試操作指令等)。
(2)測試的執行控制(包括單機與網絡多機分布運行、夜間及假日運行、測試用例調用控制、測試對象、范圍、版本控制等)。
(3)測試結果與標準輸出的對比。
(4)不吻合的測試結果的分析、記錄、分類和通報。
(5)總測試狀況的統計,報表的產生。測試自動化與軟件配置管理是密不可分的,與測試有關的資源都應在配置管理中統一考慮。
11.5 面向對象的測試
傳統的軟件測試策略是從“小型測試”開始,逐步走向“大型測試”。即從單元測試開始,然后進入集成測試,最后是系統測試。 面向對象程序的結構不再是傳統的功能模塊結構,作為一個整體,原有集成測試所要求的逐步地將開發的模塊搭建在一起進行測試的方法已成為不可能。而且,面向對象軟件拋棄了傳統的開發模式,對每個開發階段都有不同以往的要求和結果,已經不可能用功能細化的觀點來檢測面向對象分析和設計的結果。因此,傳統的測試模型對面向對象軟件已經不再適用。
1.面向對象測試模型
面向對象的開發模型突破了傳統的瀑布模型,將開發分為 OOA、OOD 和 OOP 三個階段。針對這種開發模型,結合傳統的測試步驟的劃分,可以把面向對象的軟件測試分為:面向對象分析的測試、面向對象設計的測試、面向對象編程的測試、面向對象的單元測試、面向對象的集成測試和面向對象的系統測試。
2.面向對象分析的測試
傳統的面向過程分析是一個功能分解的過程,是把一個系統看成可以分解的功能的集合。功能分解分析法的著眼點在于一個系統需要什么樣的信息處理方法和過程,以過程的抽象來對待系統的需要。而面向對象的分析直接映射問題空間,將問題空間中的實例抽象為對象,用對象的結構反映問題空間的復雜實例和復雜關系,用屬性和操作表示實例的特性和行為。
OOA 的結果是為后面階段類的選定和實現、類層次結構的組織和實現提供平臺。因此,對OOA 的測試,應從以下方面考慮:
(1)對認定的對象的測試。
(2)對認定的結構的測試。
(3)對認定的主題的測試。
(4)對定義的屬性和實例關聯的測試。
(5)對定義的服務和消息關聯的測試。
3.面向對象設計的測試
傳統的結構化設計方法,采用面向作業的思路,它把系統分解以后,提出一組作業,這些作業是以過程實現系統的基礎構造,把問題域的分析轉化為求解域的設計,分析的結果是設計階段的輸入。而 OOD 以 OOA 為基礎歸納出類,并建立類結構或進一步構造成類庫,實現分析結果對問題空間的抽象。由此可見,OOD 不是 OOA 的另一思維方式,而是 OOA 的進一步細化和更高層的抽象,OOD 與 OOA 的界限通常是難以嚴格區分的。
OOD 確定類和類結構不僅是滿足當前需求分析的要求,更重要的是通過重新組合或加以適當的補充,能夠方便地實現功能的重用和擴充,以不斷適應用戶的要求。因此,對 OOD 的測試,應從如下三方面考慮:
(1)對認定的類的測試。
(2)對構造的類層次結構的測試。
(3)對類庫的支持的測試。
4.面向對象編程的測試
典型的面向對象程序具有繼承、封裝和多態的新特性,這使得傳統的測試策略必須有所改變。封裝是對數據的隱藏,外界只能通過被提供的操作來訪問或修改數據,這樣降低了數據被任意修改和讀寫的可能性,降低了傳統程序中對數據非法操作的測試。繼承是面向對象程序的重要特點,繼承使得代碼的重用性提高,同時也使錯誤傳播的概率提高。多態使得面向對象程序對外呈現出強大的處理能力,但同時卻使得程序內 “同一”函數的行為復雜化,測試時不得不考慮對于不同類型參數具體執行的代碼和產生的行為。
面向對象程序是把功能的實現分布在類中。能正確實現功能的類,通過消息傳遞來協同實現設計要求的功能。因此,在 OOP 階段,忽略類功能實現的細則,將測試的焦點集中在類功能的實現和相應的面向對象程序風格,主要體現為以下兩個方面。
(1)數據成員是否滿足數據封裝的要求。
(2)類是否實現了要求的功能。
5.面向對象的單元測試
傳統的單元測試的對象是軟件設計的最小單位——模塊,測試依據是詳細設計說明書。單元測試應對模塊內所有重要的控制路徑設計測試用例,以便發現模塊內部的錯誤。單元測試多采用白盒測試技術,系統內多個模塊可以并行地進行測試。
對于面向對象的軟件,單元的概念發生了變化。每個類和類的實例(對象)封裝了屬性(數據)和操縱這些數據的操作,而不是個體的模塊,最小的可測試單位變成了封裝的類或對象。因此,單元測試的意義發生了較大變化。不再孤立地測試單個操作,而是將操作作為類的一部分。
6.面向對象的集成測試
傳統的集成測試,有兩種典型的集成策略:
(1)自頂向下集成,它從主控模塊開始,按照軟件的控制層次結構,以深度優先或廣度優先的策略,逐步把各個模塊集成在一起。
(2)自底向上集成,從“原子”模塊(即軟件結構最低層的模塊)開始組裝測試。面向對象的軟件沒有層次控制結構,傳統的自頂向下和自底向上集成策略已無太大意義。
此外,一次集成一個操作到類中(傳統的增量集成方法)通常是不可能的。對 OO 軟件的集成測試也有兩種不同策略:第一種稱為基于線程的測試,集成系統的一個輸入或事件所需的一組類,每個線程被集成并分別測試,并使用回歸測試以保證沒有產生副作用。第二種稱為基于使用的測試,首先測試那些幾乎不使用其他類的類(稱為獨立類)并開始構造系統,在獨立類測試完成后,下一層的使用獨立類的類(稱為依賴類)被測試。這個依賴類層次的測試序列一直持續到構造完整個系統。
7.面向對象的系統測試
通過單元測試和集成測試,僅能保證軟件開發的功能得以實現。但不能確認在實際運行時,它是否滿足用戶的需要。為此,對完成開發的軟件必須經過規范的系統測試。系統測試應該盡量搭建與用戶實際使用環境相同的測試平臺,應該保證被測系統的完整性,對臨時沒有的系統設備部件,也應有相應的模擬手段。系統測試時,應該參考 OOA 分析的結果,對應描述的對象、屬性和各種服務,檢測軟件是否能夠完全“再現”問題空間。系統測試不僅是檢測軟件的整體行為表現,從另一個側面看,也是對軟件開發設計的再確認。
面向對象測試的整體目標是以最小的工作量發現最多的錯誤,與傳統軟件測試的目標是一致的,但 OO 測試的策略與傳統測試有很大不同。這種不同主要體現在兩個方面,第一,測試的焦點從過程構件(模塊)移向了類;第二,測試的視角擴大到了分析和設計模型。