這些協作圖上的模型元素所表示的軟件系統的不同方面的信息,都是系統的本質信息,需要在軟件從設計到實現過程中必須保持的,因而軟件實現中的行為的本質方面都會在設計中表示,所以可以從設計表示中獲取行為方面的信息,用于確認軟件實現中是否正確實現。
2.2場景路徑
一個表示用例實現的協作圖實現了用例的不同事件流,包括正常流和異常流,每個事件流稱為一個場景,這些場景都被相應的協作圖實現。一個協作圖所表示的協作正是從一個外部事件觸發開始,在參與協作的對象之間完成一系列的交互,最后正確的協作結束時都導致一個外部輸出 ,對應于一個實際場景,也是一個線程執行的路徑。要找到這些路徑,一般的方法是將協作圖轉換為流圖,然后在流圖上使用圖遍歷的方法達到路徑覆蓋從而得到所有的路徑。本文為了避免復雜流圖的轉換和不可行路徑的遍歷開銷,試圖直接從協作圖上獲取這些路徑。我們從Paul C. Jorgenson[4]定義原子系統功能(ASF)和方法/消息路徑(MM-path)得到啟發,本文定義了一個場景路徑(scenario-path):
定義 場景路徑(scenario-path,s-path)是協作圖上從一個沒有前驅消息的消息開始,沿著消息的偏序執行序列,到達一個沒有后繼的消息結束的由消息相連的方法執行序列。
由于面向對象軟件的事件驅動特性,軟件的執行由事件開始,反映場景執行的場景路徑由一個外部事件觸發的消息(沒有前驅消息)開始,表示路徑入口,通過消息傳遞訪問協作圖中參與一個協作場景實現交互的對象的方法序列,達到一個引發端口輸出事件的方法且該方法自己不再發出新的消息(沒有后繼)結束,到達路徑出口,這時系統處于靜止狀態,等待另一個系統級端口輸入事件開始進一步的處理。一個場景路徑的線程的執行是一個原子執行,場景路徑表示了協作圖中的一個場景的線程執行的完整的蹤跡,也是參與協作的對象之間的交互的蹤跡,消息的傳遞激活對象方法的執行是對象之間控制流的轉移,而路徑中通過消息激活的方法調用的參數定義和使用、對象的創建、使用和撤銷明顯表示了一條在控制流上執行的數據流。
由于協作圖在表示用例實現時,協作圖上的場景路徑是從第一條入口消息開始到所有能觸發端口輸出事件或沒有后繼消息的出口消息之間的所有可能的消息流。要獲取場景路徑上的消息流,可以通過消息之間的偏序關系以及決定消息流分支和循環的條件來實現?;仡檯f作圖上消息及其順序號的定義,整數表示過程調用中相鄰高層中的消息順序,同一整數項下的不同消息是表示一個前驅-后繼式的平面控制流,嵌套的消息順序號表示過程的調用控制流。消息順序號隱含地表示了消息之間的偏序關系,因此可以在協作圖上提根據消息的發送條件及其順序號來跟蹤場景路徑。協作圖中通過消息順序號跟蹤消息執行的順序比順序圖中通過自上而下的生命線跟蹤消息執行的順序困難得多,但由于協作圖更容易表示對象之間的動態連接關系,協作圖不關注全局的消息執行順序,只關注一個場景的執行路徑上的消息順序,這為我們識別場景路徑提供了方便。協作圖上的分支和循環導致了許多可能的路徑,極端的情況下路徑的數目可能到達一個龐大的數字,我們要達到協作圖上的路徑覆蓋,采用簡單的方法達到判定/循環覆蓋。我們先將循環消息看作條件消息,在遍歷場景路徑的過程中,訪問一條消息后,先找出該消息可能的直接后繼,然后采用深度優先的方法選擇一個直接后繼繼續遍歷,當到達一個沒有后繼的消息時,就完成一個場景路徑的遍歷,回溯到下一個直接后繼,繼續遍歷,只到所有的直接后繼都已被訪問,則完成了所有的場景路徑的遍歷。這樣我們實現每條消息至少遍歷一次,每個條件分支都至少遍歷了一次,也避免了路徑的窮盡覆蓋。然后處理協作圖上的循環,一般是給出繞過循環、循環一次、循環最多次以達到循環路徑的覆蓋。對于存在分支和循環的場景路徑,例如圖1所示的協作圖上有7個條件判斷和一個最大次數為2的循環,可能的路徑有2*2*2*2*3*2*2*2=192條,但由于有5個條件判定各有一個分支直接導致場景路徑結束,所以實際的場景路徑應為1+1+1+1+1+3*2+2=13條,這13條場景路徑對應相應軟件功能的13個執行場景。
我們在協作圖上遍歷生成場景路徑的同時,很容易基于路徑覆蓋準則獲取相應場景執行過程中的控制流和數據流、覆蓋路徑的條件,然后可以確定每一路徑所需要的輸入和狀態條件,當滿足所有路徑條件時線程就會沿著該路徑執行,這正是我們定義集成測試用例所需要的信息,因此我們考慮將場景路徑作為基于協作圖的集成測試的基礎。下面我們分析協作圖表示的協作在實現中通過參與者之間的集成完成時可能發生的故障,這樣便于我們研究針對檢錯為目的的測試。
2.3基于協作圖的協作集成測試模式
協作圖上描述的軟件系統的消息的錯誤實現可能導致協作中表現的行為發生偏差,從而使最終實現與設計不一致,偏離軟件規約規定的功能。例如由于消息名的編碼錯誤、錯誤的參數、不正確的參數值、不正確的或缺少輸出以及非預期的運行時綁定導致的錯誤方法調用;消息前驅約束實現錯誤導致發送者對象發送違反接受者對象前提條件的消息或者發送者對象發送違反接受者對象的順序約束的消息;消息的發送者或接受者對象錯誤導致錯誤的對象和消息的綁定;參與者缺少功能或特征導致錯誤的對象引起正確的異常、正確的對象產生錯誤的異常。所以鏈上的消息箭頭和約束、消息標簽、對象等協作圖上的元素未按設計正確實現會導致最終的軟件與設計不一致,如果協作圖的實現中存在錯誤,肯定在協作圖至少一條路徑上,要達到該錯誤,在未知該錯誤在那條路徑上時,只能通過協作圖上選擇所有可能的執行路徑,并導出能夠跟蹤這些路徑的測試用例,并用它們來執行軟件,來確定錯誤在哪條路徑上,即哪條路徑被錯誤實現了,從而可以調試軟件,改正錯誤,以保證實現與設計一致。
這些可能發生的錯誤都是在參與協作的對象之間交互時發生,也就是系統在通過不同類的對象的方法之間集成實現系統的行為時發生,這種錯誤通常由集成測試來發現。軟件集成測試有幾種常用的集成測試模式(integration testing pattern):一次性組裝、自底向上集成、自頂向下集成、協作集成、基干集成、層次集成等,但是考慮到面向對象軟件時有的模式不一定有用,在面向對象的系統中,很難找到一個控制的層次結構,使得方便定義自底向上集成、自頂向下集成、層次集成等策略。在面向對象的環境中我們可以通過基于線程或基于使用的測試技術測試類的交互。這里交互的類可以是單個類及其實例、類簇、組件、子系統或系統。用協作圖描述的系統協作在集成測試時,協作集成是最佳的測試模式[9],通過在協作中參與的組件來決定集成測試所有參與的對象?;趨f作的集成測試需要檢測協作的參與者之間的接口和交互,通過協作組織集成。每次處理一個協作,直到協作圖上的所有協作都被測試。當所有構件的接口和構件之間的交互都測試完時集成測試完成。協作中包括的構件按照在一個處理線程、一個事件-響應路徑來選擇,要求系統中每個構件之間的消息已經被至少測試一次。我們前面定義場景路徑正是一個線程完成協作執行的一個事件-響應路徑,所以可能發生的錯誤會出現一條或多條場景路徑上。