陳君耀 祝義 欒家偉
摘要:該文針對(duì)復(fù)雜軟件系統(tǒng)測(cè)試用例自動(dòng)生成問(wèn)題,提出了一種根據(jù)軟件設(shè)計(jì)模型直接生成測(cè)試用例的方法。首先,討論了基于UML狀態(tài)圖生成測(cè)試用例的設(shè)計(jì)思路;然后給出了符合各種覆蓋要求的測(cè)試用例生成方法;最后,利用Eclipse實(shí)現(xiàn)了整個(gè)系統(tǒng)。實(shí)驗(yàn)表明該系統(tǒng)能夠根據(jù)用戶要求生成不同類型的測(cè)試用例,從而降低了復(fù)雜軟件系統(tǒng)測(cè)試用例的生成難度,并且從根本上提高了測(cè)試用例生成的有效性。
關(guān)鍵詞:統(tǒng)一建模語(yǔ)言;狀態(tài)圖;測(cè)試用例。
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2015)12-0076-03
隨著軟件技術(shù)的迅猛發(fā)展,軟件已經(jīng)成為社會(huì)各個(gè)行業(yè)中不可缺少的一部分。如今軟件的規(guī)模和復(fù)雜性日益提升,人們開(kāi)始意識(shí)到保證軟件質(zhì)量可靠性的重要性。軟件測(cè)試作為成為保證軟件質(zhì)量的關(guān)鍵性技術(shù)之一,同時(shí)也是軟件開(kāi)發(fā)過(guò)程中的一個(gè)重要環(huán)節(jié),顯得至關(guān)重要,其中設(shè)計(jì)并生成測(cè)試用例是軟件測(cè)試的關(guān)鍵。而現(xiàn)在軟件測(cè)試發(fā)展的趨勢(shì)是基于模型的測(cè)試方法,尤其是基于UML模型的測(cè)試用例生成方法易于生成滿足很高覆蓋要求的測(cè)試用例, 并運(yùn)用實(shí)例對(duì)其進(jìn)行了驗(yàn)證。本文給出了一種基于UML狀態(tài)圖模型的軟件系統(tǒng)測(cè)試用例生成方法,其目的是為了給軟件開(kāi)發(fā)的測(cè)試環(huán)節(jié)生成測(cè)試用例節(jié)省時(shí)間,以達(dá)到提高效益的目的。
1 系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
UML作為一種對(duì)軟件系統(tǒng)進(jìn)行規(guī)約、構(gòu)造、可視化和文檔化的語(yǔ)言,融合了Booch方法、OMT方法和OOSE方法的核心概念,取其精華,去其繁雜,形成一個(gè)統(tǒng)一的、公共的、具有廣泛適用性的建模語(yǔ)言。UML也可以實(shí)現(xiàn)與java之間的代碼的轉(zhuǎn)換。而且Eclipse與My Eclipse都可以實(shí)現(xiàn)畫(huà)UML的狀態(tài)圖。
1.1 需求分析
基于狀態(tài)圖的測(cè)試用例生成系統(tǒng)包括前臺(tái)子系統(tǒng)和后臺(tái)子系統(tǒng)。前臺(tái)子系統(tǒng)包括初始狀態(tài)、終止?fàn)顟B(tài)、注釋節(jié)點(diǎn)、添加狀態(tài),狀態(tài)之間的轉(zhuǎn)換。后臺(tái)子系統(tǒng)包括以下幾個(gè)子模塊:
語(yǔ)句覆蓋:每個(gè)語(yǔ)句至少執(zhí)行一次;
2)條件/判定覆蓋:在每個(gè)語(yǔ)句至少執(zhí)行一次基礎(chǔ)上,每個(gè)判定的每個(gè)分支至少執(zhí)行一次;
3)條件組合覆蓋:每個(gè)判定表達(dá)式中的各種可能組合都至少執(zhí)行一次;
4)路徑覆蓋:每條可能的路徑都至少執(zhí)行一次。
1.2 概要設(shè)計(jì)
系統(tǒng)流程圖是一種概括性地描述物理系統(tǒng)的傳統(tǒng)性工具,它的基本思想是用圖形符號(hào)以黑盒子形式描繪組成系統(tǒng)的每個(gè)部件,系統(tǒng)流程圖表達(dá)的是數(shù)據(jù)在系統(tǒng)各部件之間流動(dòng)的情況,而不是對(duì)數(shù)據(jù)進(jìn)行加工的處理的控制過(guò)程。本系統(tǒng)的系統(tǒng)流程如圖1所示。
數(shù)據(jù)流圖(DFD)是一種圖形化技術(shù),它描繪信息流和數(shù)據(jù)從輸入移動(dòng)到輸出的過(guò)程所經(jīng)受的變換,在數(shù)據(jù)流圖中沒(méi)有任何具體的物理部件,它只是描繪數(shù)據(jù)在軟件中流動(dòng)和被處理的邏輯過(guò)程。系統(tǒng)頂層數(shù)據(jù)流圖如圖2所示:
1.3 詳細(xì)設(shè)計(jì):
詳細(xì)設(shè)計(jì)階段的根本目標(biāo)是確定應(yīng)該怎樣具體地實(shí)現(xiàn)系統(tǒng)的系統(tǒng),詳細(xì)設(shè)計(jì)階段的任務(wù)還不是具體地編寫程序,而是要設(shè)計(jì)出程序的“藍(lán)圖”,將根據(jù)這個(gè)藍(lán)圖寫出實(shí)際的程序代碼,因此,詳細(xì)設(shè)計(jì)的結(jié)果基本上決定了最終的程序代碼的質(zhì)量。
本系統(tǒng)可分為前臺(tái)子系統(tǒng)和后臺(tái)子系統(tǒng),其中,前臺(tái)子系統(tǒng)主要實(shí)現(xiàn)畫(huà)圖功能,畫(huà)圖工具欄包括初始狀態(tài)、終止?fàn)顟B(tài)、注釋節(jié)點(diǎn)、添加狀態(tài),狀態(tài)之間的裝換等繪圖元素,可以通過(guò)點(diǎn)擊工具欄圖標(biāo)實(shí)現(xiàn)狀態(tài)圖的繪制。后臺(tái)子系統(tǒng)功能分為語(yǔ)句覆蓋、判定/條件覆蓋、條件組合覆蓋、路徑覆蓋的實(shí)現(xiàn)。具體設(shè)計(jì)方法如下所示:
1)語(yǔ)句覆蓋要求選擇足夠多的測(cè)試數(shù)據(jù),使得被測(cè)試程序中每個(gè)語(yǔ)句至少執(zhí)行一次。該模塊主要分為貪心算法模塊和回溯模塊,通過(guò)這兩個(gè)模塊的結(jié)合實(shí)現(xiàn)語(yǔ)句覆蓋功能,并且擴(kuò)展到其他類型的UML模型。
2)判定/條件覆蓋要求選取足夠的測(cè)試數(shù)據(jù),使得判定表達(dá)式中的每個(gè)條件都取到各種可能的布爾型值,而且每個(gè)判定表達(dá)式整體也都取到各種可能的布爾型結(jié)果。該模塊主要分為基于語(yǔ)句覆蓋基礎(chǔ)的路徑處理模塊和對(duì)選擇結(jié)構(gòu)單獨(dú)處理的模塊,依據(jù)兩個(gè)模塊的配合,實(shí)現(xiàn)判定/條件覆蓋。
3)條件組合覆蓋要求選擇足夠多的測(cè)試數(shù)據(jù),使得每個(gè)判定表達(dá)式中的各種可能組合都至少執(zhí)行一次;該模塊分為基于路徑覆蓋的主要的路徑處理提取模塊和對(duì)條件組合處理模塊以及兩者相互選擇的模塊。通過(guò)這三個(gè)模塊的有效通信,實(shí)現(xiàn)條件組合覆蓋功能。
4)路徑覆蓋要求選擇足夠多的測(cè)試數(shù)據(jù),每條可能的路徑都至少執(zhí)行一次。該模塊主要是窮舉法模塊的路徑處理和數(shù)據(jù)生成模塊。通過(guò)路徑處理模塊調(diào)用數(shù)據(jù)生成模塊,從而完成路徑覆蓋的測(cè)試用例生成。
1.4 編碼實(shí)現(xiàn)
由于整個(gè)系統(tǒng)代碼較多,在此僅選取語(yǔ)句覆蓋進(jìn)行舉例。語(yǔ)句覆蓋實(shí)現(xiàn)的思想是貪心法與回溯法相結(jié)合。利用對(duì)樹(shù)進(jìn)行遍歷的思想,利用貪心算法對(duì)語(yǔ)句進(jìn)行遍歷,每個(gè)節(jié)點(diǎn)只能遍歷一次。對(duì)于貪心算法遍歷后存在的未遍歷的結(jié)點(diǎn)利用回溯法遍歷未遍歷的結(jié)點(diǎn)的上下結(jié)點(diǎn),優(yōu)先選擇未遍歷的上下結(jié)點(diǎn),最終形成語(yǔ)句。這種結(jié)合的算法保證了語(yǔ)句覆蓋的完整性。其中的回溯函數(shù)的功能是解決因?yàn)闋顟B(tài)圖的聚合節(jié)點(diǎn)和分支節(jié)點(diǎn)照成的部分過(guò)程在單語(yǔ)句遍歷時(shí)被遺漏的情況,如果有遺漏的過(guò)程,將會(huì)優(yōu)先選擇未被遍歷的上下過(guò)程實(shí)現(xiàn)語(yǔ)句的生成,即實(shí)現(xiàn)回溯功能,從而保證語(yǔ)句覆蓋的完整性。
語(yǔ)句覆蓋主要代碼如下:
public void SentenceCover(Swant s[],int n)
{
String eventpath[][]=new String[50][2];
String orgin = "start";//是用來(lái)遍歷過(guò)程時(shí)存儲(chǔ)下個(gè)過(guò)程的起始點(diǎn)的信息
String preorgin=orgin;
int rows=0;
int isrest;
int count=0;
int i;//循環(huán)變量
while(count { count++; for(i=0;i { if (s[i].start.equals(orgin)&&s[i].state==1)//尋找到下一個(gè)節(jié)點(diǎn)時(shí)進(jìn)行操作 { s[i].state=0; if(s[i].start=="start")//當(dāng)路徑剛開(kāi)始時(shí) { eventpath[rows][0]=s[i].sevent+" ";//存儲(chǔ)路徑的事件 eventpath[rows][1]=s[i].start+"->"+s[i].end;//存儲(chǔ)路徑 } else { eventpath[rows][0]=eventpath[rows][0]+s[i].sevent+" ";//存儲(chǔ)路徑的事件 eventpath[rows][1]=eventpath[rows][1]+"->"+s[i].end;//存儲(chǔ)路徑 } if(s[i].end.equals("end"))//當(dāng)下一個(gè)節(jié)點(diǎn)為結(jié)束節(jié)點(diǎn)時(shí)的操作 { orgin="start"; preorgin=orgin; count=0; rows++; break; } else //當(dāng)下一個(gè)節(jié)點(diǎn)不是結(jié)束節(jié)點(diǎn)時(shí)的操作 { preorgin=orgin; orgin=s[i].end; } } else //不是下一節(jié)點(diǎn)時(shí)繼續(xù)循環(huán) continue; } } isrest=Isrest(s, n);//測(cè)試是否有剩余節(jié)點(diǎn)沒(méi)有遍歷 while(isrest!=-1||orgin!="start")//進(jìn)行回溯或者填補(bǔ)完整路徑 { BackTracking(s,n,eventpath,isrest,rows,orgin);//回溯函數(shù) orgin="start"; rows++; isrest=Isrest(s, n); //System.out.println(isrest+" "+orgin); } for(i=0;i { System.out.println(eventpath[i][0]); System.out.println(eventpath[i][1]); } F f=new F(eventpath,rows,"語(yǔ)句覆蓋"); } 狀態(tài)圖的語(yǔ)句覆蓋示例如圖4所示。 2 結(jié)束語(yǔ) 本文針對(duì)基于UML狀態(tài)圖的軟件系統(tǒng)測(cè)試用例生成方法及工具研究進(jìn)行了討論。首先,討論了基于UML狀態(tài)圖生成測(cè)試用例的設(shè)計(jì)思路;然后給出了符合各種覆蓋要求的測(cè)試用例生成方法;最后,利用Eclipse實(shí)現(xiàn)了整個(gè)系統(tǒng)。實(shí)驗(yàn)表明該系統(tǒng)能夠根據(jù)用戶要求生成不同類型的測(cè)試用例,降低了復(fù)雜軟件系統(tǒng)測(cè)試用例的生成難度,提高了系統(tǒng)測(cè)試用例生成的正確性和可靠性。 參考文獻(xiàn): [1] 李相國(guó). Java實(shí)例精通[M]. 北京: 機(jī)械工業(yè)出版社, 2009: 3-36. [2] 明日科技. Java從入門到精通 [M]. 3版. 北京: 清華大學(xué)出版社, 2012. [3] 袁濤, 孫蕾蕾. 統(tǒng)一建模語(yǔ)言UML[M]. 北京: 清華大學(xué)出版社, 2009. [4] 張永常. Java程序設(shè)計(jì)實(shí)用教程[M]. 2版. 北京: 電子工業(yè)出版社, 2009: 78-276. [5] 張海藩. 軟件工程導(dǎo)論[M]. 北京: 清華大學(xué)出版社, 1998.