3、基于協作圖生成集成測試用例的方法
3.1研究假定
為了有針對性地解決從協作圖生成測試用例的問題,本文作出如下假定和要求:
(1)假定協作圖描述的協作與用例圖描述的規約是一致的。模型本身的驗證是通過非形式化的復審和形式化的模型檢驗方法進行的,已超出本文的研究范圍;如果協作圖上的場景路徑集不能覆蓋所有消息,則說明協作圖本身有錯誤;
(2)假定系統中的對象都是自行開發的,不包括第三方組件對象,文中的對象可以是不同粒度的對象(類的實例、類簇、組件、子系統、系統),也就是說我們在分析任意對象或類時,在必要的情況下都可以獲取其規約和內部詳細設計信息,包括功能和結構信息;對于第三方組件的集成測試,[13][17]介紹了詳細的測試方法;
(3)我們研究的測試是針對檢錯進行的,確認軟件是否正確實現了設計,協作圖上的結構關系是否被正確實現,[15]中已有相應的靜態檢驗方法,所以本文只研究動態交互行為的測試;
(4)本文為了明確解決問題,假定消息類型只有普通消息、條件消息、循環消息,而且只存在順序循環,不存在嵌套循環。
3.2方法概述
基于協作圖的集成測試(Collaboration diagram-based Integration Testing, CIT )方法集合了傳統的白盒測試方法和黑盒測試方法,用于測試協作圖中參與協作的對象之間通過消息的交互,對每個協作圖處理一次,得到相應的測試用例集。首先分析協作圖,提取協作圖中表示的所有元素,根據消息的順序號和消息的條件,找到每一條消息的直接后繼消息,然后根據場景路徑的定義,使用深度優先方法遍歷消息及其直接后繼直至到達無直接后繼的消息從而生成場景路徑,然后回溯到沒有被訪問的直接后繼,重復上述方法找到所有的場景路徑;在訪問消息獲取場景路徑的同時,獲取該路徑的方法調用序列、參數和路徑條件,將這些集成測試的關鍵因素用范疇-劃分方法定義為方法序列、環境條件、系統輸入、系統輸出等范疇,結合該協作片斷的用例規約和類圖中的定義生成這些范疇的可能選擇,然后結合路徑約束條件在這些范疇的劃分中確定選擇項的合理組合,這樣我們就等到了該場景路徑完整的測試用例,包括外界輸入、交互輸入、預期方法調用序列、后條件、預期輸出。對協作圖中的所有場景路徑都構造了測試用例,就形成了協作集成測試用例集。這樣在實際執行集成測試時不但可以直接觀察到系統級的輸入作用下協作實現過程中的實際輸出,還能夠通過動態插裝方法在代碼中加入不影響軟件功能的觀察代碼[15],使測試人員能夠觀察到實際協作執行時的方法調用序列和數據流的定義和使用,然后通過比較最終系統實際執行時輸出與預期輸出的一致性決定該協作實現的功能是否正確,通過比較應該發生的方法調用序列和實際執行時觀察到的方法調用序列是否一致,確定協作表示的交互行為是否正確,從而從整體上對協作圖描述的系統行為的實現是否與設計一致,從而完成協作的集成測試。
本方法可以以增量的方法進行,最終生成的測試用例的具體程度,與相應UML模型圖的設計精化程度相關,因為協作圖描述的場景的詳細程度與測試用例的表達能力直接相關。
3.3 UML協作圖生成測試用例的算法描述
本文的方法能夠從協作圖規約文檔直接生成測試用例,主要描述分析協作圖規約文檔提取集成測試需求信息并生成消息后繼表的算法UMLspecificationparser(),然后為每個消息確定其直接后繼消息的findsuccessor()算法,根據消息后繼表遍歷所有場景路徑獲取測試用例規約信息的spathgenerator()算法,以及從測試用例規約使用范疇劃分方法確定測試用例輸入值、預期輸出值、預期輸出行為的算法testcasegenerator()。UMLspecificationparser()算法從協作圖從獲取集成測試需求信息是通過對UML協作圖規約的文本文件(如Rational Rose 的MDL文件)進行分析完成的[11],在我們的工具中實現相應的功能,本文對分析算法不作詳細描述。我們用鄰接表定義消息后繼列表,將分析結果信息按消息順序號升序記錄到messagelist的表頭中,以便下一步處理。我們定義消息后繼列表如下:
messageitem{
mid:string;//消息順序號
mguardcondition:string;//消息衛式條件表達式
mlabel:string;//消息標簽
msender,mreciever:object;// 消息發送者對象,消息接收者對象
mmethod:method;//消息激活的方法
mtype:[flat flow, procdure call, call return];// 根據消息的箭頭及線型劃分的消息類型
link:pointer of msuccessor;
}
msuccessor{
mid:string;//后繼消息順序號
mscondition:string;//選擇該后繼的條件表達式
next:pointer of msuccesor
}
messagelist:messageitem[n];
findsuccessor()算法為消息生成直接后繼列表的并記錄到消息的后繼鏈表中,描述如下:
findsuccessor(messagelist){ //找到所有消息的所有可能后繼和每個后繼條件
//輸入:消息后繼表messagelist
//輸出:消息后繼表messagelist
//出口準則:所有消息都處理完
for i:=1 to n do {
if i= =n 或者messagelist[i]為端口輸出事件觸發消息
messagelist[i].link=nil;i:=i+1; //最后消息或觸發端口輸出事件的消息無后繼消息
else{
if messagelist[i+1]是普通消息
則messagelist[i]的直接后繼為messagelist[i+1];
else{
k:=1;
do while messagelist[i+k]是條件消息{
messagelist [i+k]是messagelist [i]的直接后繼,且條件為messagelist [i+k]的條件取真
if messagelist [i+k]是循環或嵌套層次的第一個消息{
t:=該層次的消息數;messagelist [i+k+t]是messagelist [i]的直接后繼;
條件為messagelist [i+k]的條件取假; k:=k+t;}//條件取假時循//環或嵌套內的消息都不發送
else{
messagelist [i+k+1]是messagelist [i]的直接后繼;
條件為messagelist [i+1]的條件取假; k:=k+1;//不發送
}endif
}enddo
}endif
i:=i+1;
}endif
}endfor;
}endfindsuccessor;
spathgenerator()通過訪問消息后繼表中消息及其直接后繼生成場景路徑,在遍歷場景路徑時同時記錄路徑上相應的控制流和數據流信息,執行完畢得到一個場景路徑集spath相應的控制流數據流測試規約。其算法描述如下:
s-pathgenerator(m:msuccessorlist){
//輸入:messagelist; (消息后繼表)
//輸出:spath;(場景路徑集)
spath{
sid:integer;//場景路徑順序號
pathcondition: list of gardcondition; //場景路徑的實現條件
mlist:list of message;//場景路徑上的消息流列表
parameters:list of variable;//場景路徑上定義和使用的變量列表
userinputparameters: list of variable; //場景路徑上外界輸入參數列表
methodsequence:{objectname,methodname,next};場景路徑上由消息激活的方法序列
}[n];
i,j:integer;
i:=1; j:=1;
Sid:=j;//場景路徑序號
//遞歸訪問消息及其直接后繼
訪問消息m,在消息標簽中取出并記錄返回值、參數、調用的對象方法;
記錄消息條件到路徑條件中;
if m的后繼消息為空
{ 一條場景路徑結束;j:=j+1;return;}//回溯到m[i]的直接前驅繼續
else{
k:=1;
while m.link<>nil do { //m的后繼消息列表不空
successor:=m.link;
spathgenerator(successor) //深度優先遍歷該消息及其后繼消息
m.link:=successor->next;//下一后繼消息;
}endwhile
}endif;
}endfind;
文章來源于領測軟件測試網 http://www.k11sc111.com/