軟件的質量不僅是體現在程序的正確性上,它和編碼以前所做的需求分析,軟件設計也密切相關。這時,對錯誤的糾正往往不能通過可能會誘發更多錯誤的簡單的修修補補,而必須追溯到軟件開發的最初階段。因此,為了保證軟件的質量,我們應該著眼于整個軟件生存期,特別是著眼于編碼以前的各開發階段的工作。于是,軟件測試的概念和實施范圍必須擴充,應該包括在整個開發各階段的復查、評估和檢測。由此,廣義的軟件測試實際是由確認、驗證、測試三個方面組成。
在整個軟件生存期,確認、驗證、測試分別有其側重的階段。確認主要體現在計劃階段、需求分析階段、也會出現在測試階段;驗證主要體現在設計階段和編碼階段;測試主要體現在編碼階段和測試階段。事實上,確認、驗證、測試是相輔相成的。確認無疑會產生驗證和測試的標準,而驗證和測試通常又會幫助完成一些確認,特別是在系統測試階段。
傳統的測試計算機軟件的策略是從“小型測試”開始,逐步走向“大型測試”。即我們從單元測試開始,然后逐步進入集成測試,最后是有效性和系統測試。在傳統應用中,單元測試集中在最小的可編譯程序單位——子程序(如,模塊、子例程、進程),一旦這些單元均被獨立測試后,它被集成在程序結構中,這時要進行一系列的回歸測試以發現由于模塊的接口所帶來的錯誤和新單元加入所導致的副作用,最后,系統被作為一個整體測試以保證發現在需求中的錯誤。
面向對象程序的結構不再是傳統的功能模塊結構,作為一個整體,原有集成測試所要求的逐步將開發的模塊搭建在一起進行測試的方法已成為不可能。而且,面向對象軟件拋棄了傳統的開發模式,對每個開發階段都有不同以往的要求和結果,已經不可能用功能細化的觀點來檢測面向對象分析和設計的結果。因此,傳統的測試模型對面向對象軟件已經不再適用。
1面向對象測試模型
面向對象的開發模型突破了傳統的瀑布模型,將開發分為面向對象分析(OOA),面向對象設計(OOD),和面向對象編程(OOP)三個階段。針對這種開發模型,結合傳統的測試步驟的劃分,我們把面向對象的軟件測試分為:面向對象分析的測試,面向對象設計的測試,面向對象編程的測試,面向對象單元測試,面向對象集成測試,面向對象系統測試。
2面向對象分析的測試
傳統的面向過程分析是一個功能分解的過程,是把一個系統看成可以分解的功能的集合。這種傳統的功能分解分析法的著眼點在于一個系統需要什么樣的信息處理方法和過程,以過程的抽象來對待系統的需要。而面向對象分析(OOA)是"把E-R圖和語義網絡模型,即信息造型中的概念,與面向對象程序設計語言中的重要概念結合在一起而形成的分析方法",最后通常是得到問題空間的圖表的形式描述。OOA直接映射問題空間,全面的將問題空間中實現功能的現實抽象化。將問題空間中的實例抽象為對象,用對象的結構反映問題空間的復雜實例和復雜關系,用屬性和操作表示實例的特性和行為。對一個系統而言,與傳統分析方法產生的結果相反,行為是相對穩定的,結構是相對不穩定的,這更充分反映了現實的特性。OOA的結果是為后面階段類的選定和實現,類層次結構的組織和實現提供平臺。因此,對OOA的測試,應從以下方面考慮:
對認定的對象的測試
對認定的結構的測試
對認定的主題的測試
對定義的屬性和實例關聯的測試
對定義的服務和消息關聯的測試
3面向對象設計的測試
通常的結構化的設計方法,用的"是面向作業的設計方法,它把系統分解以后,提出一組作業,這些作業是以過程實現系統的基礎構造,把問題域的分析轉化為求解域的設計,分析的結果是設計階段的輸入"。而面向對象設計(OOD)采用"造型的觀點",以OOA為基礎歸納出類,并建立類結構或進一步構造成類庫,實現分析結果對問題空間的抽象。由此可見,OOD不是在OOA上的另一思維方式的大動干戈,而是OOA的進一步細化和更高層的抽象。所以,OOD與OOA 的界限通常是難以嚴格區分的。OOD確定類和類結構不僅是滿足當前需求分析的要求,更重要的是通過重新組合或加以適當的補充,能方便實現功能的重用和擴增,以不斷適應用戶的要求。因此,對OOD的測試,應從如下三方面考慮:
對認定的類的測試
對構造的類層次結構的測試
對類庫的支持的測試
4面向對象編程的測試
典型的面向對象程序具有繼承、封裝和多態的新特性,這使得傳統的測試策略必須有所改變。封裝是對數據的隱藏,外界只能通過被提供的操作來訪問或修改數據,這樣降低了數據被任意修改和讀寫的可能性,降低了傳統程序中對數據非法操作的測試。繼承是面向對象程序的重要特點,繼承使得代碼的重用率提高,同時也使錯誤傳播的概率提高。多態使得面向對象程序對外呈現出強大的處理能力,但同時卻使得程序內"同一"函數的行為復雜化,測試時不得不考慮不同類型具體執行的代碼和產生的行為。
面向對象程序是把功能的實現分布在類中。能正確實現功能的類,通過消息傳遞來協同實現設計要求的功能。因此,在面向對象編程(OOP)階段,忽略類功能實現的細則,將測試的目光集中在類功能的實現和相應的面向對象程序風格,主要體現為以下兩個方面。
數據成員是否滿足數據封裝的要求
類是否實現了要求的功能
5面向對象的單元測試
傳統的單元測試的對象是軟件設計的最小單位——模塊。單元測試的依據是詳細設描述,單元測試應對模塊內所有重要的控制路徑設計測試用例,以便發現模塊內部的錯誤。單元測試多采用白盒測試技術,系統內多個模塊可以并行地進行測試。
當考慮面向對象軟件時,單元的概念發生了變化。封裝驅動了類和對象的定義,這意味著每個類和類的實例(對象)包裝了屬性(數據)和操縱這些數據的操作。而不是個體的模塊。最小的可測試單位是封裝的類或對象,類包含一組不同的操作,并且某特殊操作可能作為一組不同類的一部分存在,因此,單元測試的意義發生了較大變化。我們不再孤立地測試單個操作,而是將操作作為類的一部分。
6面向對象的集成測試
傳統的集成測試,有兩種方式通過集成完成的功能模塊進行測。(一)自頂向下集成:自頂向下集成是構造程序結構的一種增量式方式,它從主控模塊開始,按照軟件的控制層次結構,以深度優先或廣度優先的策略,逐步把各個模塊集成在一起。(二)自底向上集成:自底向上測試是從“原子”模塊(即軟件結構最低層的模塊)開始組裝測試。
因為面向對象軟件沒有層次的控制結構,傳統的自頂向下和自底向上集成策略就沒有意義,此外,一次集成一個操作到類中(傳統的增量集成方法)經常是不可能的,這是由于“構成類的成分的直接和間接的交互”。對OO軟件的集成測試有兩種不同策略,第一種稱為基于線程的測試,集成對回應系統的一個輸入或事件所需的一組類,每個線程被集成并分別測試,應用回歸測試以保證沒有產生副作用。第二種稱為基于使用的測試,通過測試那些幾乎不使用服務器類的類(稱為獨立類)而開始構造系統,在獨立類測試完成后,下一層的使用獨立類的類,稱為依賴類,被測試。這個依賴類層次的測試序列一直持續到構造完整個系統。
7面向對象的系統測試
通過單元測試和集成測試,僅能保證軟件開發的功能得以實現。但不能確認在實際運行時,它是否滿足用戶的需要。為此,對完成開發的軟件必須經過規范的系統測試。系統測試應該盡量搭建與用戶實際使用環境相同的測試平臺,應該保證被測系統的完整性,對臨時沒有的系統設備部件,也應有相應的模擬手段。系統測試時,應該參考OOA分析的結果,對應描述的對象、屬性和各種服務,檢測軟件是否能夠完全"再現"問題空間。系統測試不僅是檢測軟件的整體行為表現,從另一個側面看,也是對軟件開發設計的再確認。
面向對象測試的整體目標——以最小的工作量發現最多的錯誤——和傳統軟件測試的目標是一致的,但是OO測試的策略和戰術有很大不同。測試的視角擴大到包括復審分析和設計模型,此外,測試的焦點從過程構件(模塊)移向了類。
不論是傳統的測試方法還是面向對象的測試方法,我們都應該遵循下列的原則:
1.應當把“盡早和不斷地測試”作為開發者的座右銘。
2.程序員應該避免檢查自己的程序,測試工作應該由獨立的專業的軟件測試機構來完成。
3.設計測試用例時,應該考慮到合法的輸入和不合法的輸入,以及各種邊界條件,特殊情況下要制造極端狀態和意外狀態,比如網絡異常中斷、電源斷電等情況。
4.一定要注意測試中的錯誤集中發生現象,這和程序員的編程水平和習慣有很大的關系。
5.對測試錯誤結果一定要有一個確認的過程。一般有A測試出來的錯誤,一定要有一個B來確認,嚴重的錯誤可以召開評審會進行討論和分析。
6.制定嚴格的測試計劃,并把測試時間安排得盡量寬松,不要希望在極短的時間內完成一個高水平的測試。
7.回歸測試的關聯性一定要引起充分的注意,修改一個錯誤而引起更多錯誤出現的現象并不少見。
8.妥善保存一切測試過程文檔,意義是不言而喻的,測試的重現性往往要靠測試文檔。
原文轉自:http://www.anti-gravitydesign.com