基于語義變異算子的測試用例生成和優(yōu)化方法
【專利摘要】本發(fā)明涉及一種基于語義變異算子的測試用例生成和優(yōu)化方法,其特點(diǎn)是主要包括兩個(gè)部分:一是測試用例的生成,即結(jié)合語義變異算子和混合執(zhí)行生成覆蓋率盡可能高的初始測試用例集;二是對初始測試用例集進(jìn)行優(yōu)化,即通過對初始測試用例集在各語義變異體執(zhí)行中的故障檢測結(jié)果和運(yùn)行狀態(tài)捕獲,根據(jù)本發(fā)明提出的相關(guān)指標(biāo)對其進(jìn)行優(yōu)化,并評估優(yōu)化后的測試用例集。
【專利說明】
基于語義變異算子的測試用例生成和優(yōu)化方法
技術(shù)領(lǐng)域
[0001] 本發(fā)明屬于軟件測試中測試用例生成和優(yōu)化方法,涉及變異測試方法,測試用例 生成方法,測試用例集優(yōu)化方法等。
【背景技術(shù)】
[0002] 文南犬 "Lingming Zhang, Tao Xie ,Lu Zhang Test Generation via Dynamic Symbolic Execution for Mutation Testing,ICSM'lOProceedings of the 2010IEEE International Conference on Software Maintenance,Pagesl_10"公開了一種基于變異 測試和動態(tài)符號執(zhí)行結(jié)合的測試用例生成方法。該方法通過搜集隨機(jī)生成測試用例的執(zhí)行 路徑,對執(zhí)行路徑上的最后一個(gè)謂詞進(jìn)行取反操作,并生成一個(gè)新的路徑條件。如果該執(zhí)行 路徑不存在,則調(diào)用約束求解器求解生成新的測試用例。若存在,則對其之前的謂詞進(jìn)行取 反,依次類推。當(dāng)不能生成新的路徑條件時(shí),使用動態(tài)符號執(zhí)行進(jìn)行的測試用例生成過程結(jié) 束。在生成的測試用例中將滿足強(qiáng)變異測試條件的用例輸入,其他用例則拋棄。利用該方法 生成的測試用例雖然具有較高的變異評分,但由于其使用了傳統(tǒng)的語法變異測試技術(shù),在 應(yīng)用過程中時(shí)間和資源消耗較為嚴(yán)重,而且由于動態(tài)符號執(zhí)行引發(fā)的過程阻塞也經(jīng)常發(fā) 生。
【發(fā)明內(nèi)容】
[0003] 要解決的技術(shù)問題
[0004] 為了克服現(xiàn)有基于語法變異的測試用例生成方法中變異代價(jià)高、資源消耗嚴(yán)重以 及生成測試用例充分性不強(qiáng)的不足,本發(fā)明提出一種基于語義變異算子的測試用例生成和 優(yōu)化方法。該方法引入了語義變異算子來代替?zhèn)鹘y(tǒng)的語法變異算子,利用高效的程序語義 變異來降低生成變異體的時(shí)間、資源消耗,在此基礎(chǔ)上通過混合執(zhí)行對語義變異體的執(zhí)行 路徑進(jìn)行求解,生成對應(yīng)的測試用例。通過實(shí)際測試結(jié)果證明,本發(fā)明提出的方法能夠利 用較少資源和時(shí)間消耗生成充分性較高的測試用例。
[0005] 技術(shù)方案
[0006] 本發(fā)明解決其技術(shù)問題所采用的技術(shù)方案是:一種基于語義變異算子的測試用例 生成和優(yōu)化方法,其特點(diǎn)是主要包括兩個(gè)部分:一是測試用例的生成,即結(jié)合語義變異算子 和混合執(zhí)行生成覆蓋率盡可能高的初始測試用例集;二是對初始測試用例集進(jìn)行優(yōu)化,即 通過對初始測試用例集在各語義變異體執(zhí)行中的故障檢測結(jié)果和運(yùn)行狀態(tài)捕獲,根據(jù)本發(fā) 明提出的相關(guān)指標(biāo)對其進(jìn)行優(yōu)化,并評估優(yōu)化后的測試用例集。
[0007] -種基于語義變異算子的測試用例生成和優(yōu)化方法,其特征在于步驟如下:
[0008] 步驟1:將被測源程序作為輸入,將語義變異算子作用于源程序,生成相對應(yīng)的語 義變異體;
[0009] 步驟2:使用基于混合執(zhí)行的測試用例自動化生成工具jCUTE中的jcutec命令對語 義變異體進(jìn)行插粧和編譯,生成.class文件,然后使用jcute命令對.class文件進(jìn)行混合執(zhí) 行,生成與語義變異體相對應(yīng)的初始測試用例;
[00?0] 步驟3:將每個(gè)初始測試用例作為輸入,使用程序驗(yàn)證工具Java PathFinder執(zhí)行 所有的語義變異體,得到每個(gè)初始測試用例相對應(yīng)的執(zhí)行結(jié)果:產(chǎn)生變異體總數(shù)量!^,單個(gè) 測試用例執(zhí)行一個(gè)變異體的時(shí)間消耗^,殺死變異體總數(shù)量K m,等價(jià)變異體個(gè)數(shù)Em;
[0011]步驟4:依據(jù)執(zhí)行結(jié)果對初始測試用例先進(jìn)行MS優(yōu)化,再進(jìn)行AC優(yōu)化,得到優(yōu)化的 測試用例排序:
[0012]所述的MS優(yōu)化,即將測試用例按照變異評分降序排列,定義為:
[0014] 其中,Km為殺死變異體總數(shù)量,Tm為產(chǎn)生變異體總數(shù)量,Em為等價(jià)變異體個(gè)數(shù);
[0015] 所述的AC優(yōu)化,即將測試用例按照平均時(shí)間消耗升序排列,定義為:
[0017] 其中,tn為單個(gè)測試用例執(zhí)行一個(gè)變異體的時(shí)間消耗,1"為執(zhí)行變異體總數(shù)量。
[0018] 所述步驟1中的語義變異算子包括以下20種:
[0019] 1)RVK:移除volatile關(guān)鍵字:將volatile移除后,變量會被線程保存在本地的內(nèi) 存空間中,而并非直接在主存中進(jìn)行讀寫,最終導(dǎo)致數(shù)據(jù)讀寫的不一致;
[0020] 2)SPCR:分割臨界區(qū),將一個(gè)臨界區(qū)分割為兩個(gè)臨界區(qū),每個(gè)臨界區(qū)中的代碼都仍 然是受保護(hù)的,但是原臨界區(qū)的代碼集合會改變屬性;
[0021] 3)MSBP:Synchronizaed同步塊的參數(shù)通常有this關(guān)鍵字或相關(guān)對象,該變異算子 是將this關(guān)鍵字或相關(guān)對象替換;
[0022] 4)SHCR:移動臨界區(qū),將臨界區(qū)上移或下移可能會引起沖突故障,這時(shí)共享的資源 不在是同步的了;
[0023] 5)SKCR:縮小臨界區(qū),將臨界區(qū)的代碼移動到非臨界區(qū),會引發(fā)數(shù)據(jù)競爭;
[0024] 6)ASTK:添加 Static關(guān)鍵詞,在一個(gè)同步方法中使用static關(guān)鍵詞表示這個(gè)類對 象不是一個(gè)實(shí)例對象,如果將一個(gè)非靜態(tài)同步方法變?yōu)殪o態(tài)同步方法就會使之變?yōu)閷?shí)例對 象,引起錯誤的鎖故障;
[0025] 7)RSTK:移除靜態(tài)方法中的static關(guān)鍵詞;
[0026] 8)RSB:移除同步塊,引起程序缺失必要的鎖,從而導(dǎo)致同步錯誤;
[0027] 9)MSL:改變同步塊的位置,使未被初始化完成的對象被引用,可以導(dǎo)致雙重驗(yàn)證 的故障;
[0028] 10 )MXT:作用于wai t ()、s 1 eep ()和jo in ()方法,改變這些方法包含的時(shí)間參數(shù),該 變異算子使用相同類型不同值替換了時(shí)間參數(shù),使線程等待的時(shí)間延長或是縮短,從而改 變了線程等待的時(shí)間;
[0029] 11 )RTXC:將wait()、join()、sleep()、yield()、notify()和notifyAll ()方法調(diào)用 移除,移除wait()方法可以引起可能的沖突,移除join()和sleep()方法能夠引起sleep() 故障;
[0030] 12)RJS:將 join〇 方法替換為 sleepO 方法;
[0031 ] 13)RCXC:將以下并行機(jī)制移除:Locks( lock()、unlock()),Condit ion (signal ()、 signalAll()),Semaphore(acquire()、release()),Latch(countDown()), ExecutorService(submit()),在該語義變異算子的作用下,會導(dǎo)致臨界區(qū)缺失故障;
[0032] 14 )RFU:將unlock周圍的finally語句移除,finally保證了鎖最后被釋放,如果該 語句被移除,那么發(fā)生異常的時(shí)候不能保證鎖被最終釋放,會導(dǎo)致臨界資源缺失的故障; [0033] 15)ASK/RSK:添加/移除方法中的Synchronized關(guān)鍵詞,如果該方法中存在臨界 區(qū),則ASK會引發(fā)死鎖故障,而RSK則是程序員經(jīng)常會犯的錯誤,可能會引發(fā)鎖缺失的故障; [0034] 16)EXCR:擴(kuò)展臨界區(qū),將非臨界區(qū)的代碼添加到臨界區(qū)中,當(dāng)另一個(gè)臨界區(qū)也包 含這些代碼時(shí),會引發(fā)死鎖;
[0035] 17) RNA:將no t i f yA 11 ()方法替換為no t i f y ()方法;
[0036] 18)MSF:改變信號量的公平性,信號量維護(hù)了進(jìn)入資源的許可集合,在信號量的構(gòu) 造函數(shù)中有一個(gè)可選的Boolean參數(shù),當(dāng)這個(gè)參數(shù)設(shè)為false時(shí)允許不公平地獲得許可,MSF 是將該參數(shù)的true值替換為false或者false替換為true;
[0037] 19 )MXC:作用于并發(fā)機(jī)制:Semaphores、Latches和Barr iers,改變其使用數(shù)量;
[0038] 20 )MBR:改變CyclicBarrier類中構(gòu)造函數(shù)中runnable參數(shù),這個(gè)參數(shù)是在所有的 線程完成并且到達(dá)這個(gè)barrier時(shí)發(fā)生的,如果這個(gè)可執(zhí)行線程參數(shù)存在的話將它移除。 [0039] 一種對優(yōu)化測試用例排序進(jìn)行評估的方法,其特征在于使用APFD評估標(biāo)準(zhǔn)對候 選的測試用例集排序進(jìn)行評估;所述的APFD為故障檢測平均百分比,定義為:
[0041]其中,η是測試用例的數(shù)量,m表示程序中錯誤的個(gè)數(shù),1?1是第一個(gè)檢測到故障的 測試用例的位置;APFD越大,測試用例集發(fā)現(xiàn)錯誤的速度越快,這樣的測試用例序列就越 好。
[0042] 有益效果
[0043] 本發(fā)明提出的一種基于語義變異算子的測試用例生成和優(yōu)化方法,有益效果:
[0044] 語義變異能夠使用較少的開銷達(dá)到理想的變異效果,本發(fā)明提出的方法通過設(shè)計(jì) 一系列的語義變異算子,實(shí)現(xiàn)了對程序的語義變異,從而進(jìn)一步利用混合執(zhí)行方法生成語 義變異體的測試用例,最后基于變異評分和消耗對測試用例集進(jìn)行優(yōu)化。該方法克服了傳 統(tǒng)語法變異測試高消耗的不足,也彌補(bǔ)基于動態(tài)符號執(zhí)行測試用例生成技術(shù)過程阻塞的缺 陷,經(jīng)測試使用該方法提高了測試用例生成的效率和覆蓋率。
【附圖說明】
[0045] 圖1是基于語義變異算子的測試用例生成和優(yōu)化方法總流程圖;
[0046]圖2是AirLine程序?qū)嶒?yàn)結(jié)果;
[0047]圖3是Account程序?qū)嶒?yàn)結(jié)果;
[0048] 圖4是DiningPhi程序?qū)嶒?yàn)結(jié)果;
[0049] 圖5是LinkedList程序?qū)嶒?yàn)結(jié)果;
[0050] 圖6是UnsortedTree程序?qū)嶒?yàn)結(jié)果;
[0051]圖7是RayTracer程序?qū)嶒?yàn)結(jié)果;
[0052] 圖8是MoldDyn程序?qū)嶒?yàn)結(jié)果。
【具體實(shí)施方式】
[0053]現(xiàn)結(jié)合實(shí)施例、附圖對本發(fā)明作進(jìn)一步描述:
[0054]參照圖1?;谡Z義變異算子的測試用例生成和優(yōu)化方法主要包括以下步驟:
[0055] 1、生成語義變異體
[0056] 語義變異體的生成是以被測源程序作為輸入,將語義變異算子作用于源程序,生 成相對應(yīng)的語義變異體。那么。該過程首先依賴于語義變異算子的設(shè)計(jì)和實(shí)現(xiàn),具體的,我 們定義程序描述語言為N,程序語義為L,程序的執(zhí)行行為為(N,L)。不同于傳統(tǒng)的語法變異 操作(N,L) - (N',L),語義變異算子的操作方式為(N,L) - (N,L')。如果更改前后分別執(zhí)行 一個(gè)測試用例t,其程序的行為不一致,則認(rèn)為t殺死了這個(gè)變異體。為了描述這種行為不一 致,我們引入了程序的語義錯誤模型。對于每一個(gè)程序P,定義其輸入域?yàn)榧螪,輸出范圍 為集合R,以及一個(gè)規(guī)約說明S,表示從D到R的映射。P是對D上的一個(gè)超集進(jìn)行計(jì)算,如果一 個(gè)輸入不在D內(nèi),那么其在P上的輸出也不在R內(nèi)。程序錯誤的語義特征描述了一個(gè)在輸入域 子集上生成不正確輸出的計(jì)算結(jié)果,也就是從輸入到輸出的一個(gè)不正確的映射關(guān)系。這種 正確與否的標(biāo)準(zhǔn)模型表示,能更好地描述程序行為的不一致性,便于我們尋找程序的錯誤 場景。
[0057] 對于特定的錯誤場景,需要對應(yīng)的語義變異算子實(shí)現(xiàn)模擬程序真實(shí)的故障,來評 估現(xiàn)有的測試集或者指導(dǎo)生成新的測試用例集。因此,如何將錯誤植入程序,即通過語義變 異算子生成變異體,是語義變異最為關(guān)鍵的問題。本發(fā)明針對目前最為流行的Java并行程 序,分析研究了 Java并行程序的故障模式,并在此基礎(chǔ)上設(shè)計(jì)了面向Java并行程序的語義 變異算子。具體的,本發(fā)明設(shè)計(jì)了 20個(gè)語義變異算子,定義如下:
[0058] l)RVK(Remove Volatile Keyword):移除volatile關(guān)鍵字。將volatile移除后,變 量會被線程保存在本地的內(nèi)存空間中,而并非直接在主存中進(jìn)行讀寫,最終導(dǎo)致數(shù)據(jù)讀寫 的不一致。
[0059] 2)SPCR(Split Critical Region):分割臨界區(qū),將一個(gè)臨界區(qū)分割為兩個(gè)臨界 區(qū),每個(gè)臨界區(qū)中的代碼都仍然是受保護(hù)的,但是原臨界區(qū)的代碼集合會改變屬性。
[0060] 3)MSBP(Modify Synchronized Block Parameter): Synchronizaed同步塊的參數(shù) 通常有this關(guān)鍵字或相關(guān)對象,該變異算子是將this關(guān)鍵字或相關(guān)對象替換。
[0061 ] 4)SHCR(Shift Critical Region):移動臨界區(qū),將臨界區(qū)上移或下移可能會引起 沖突故障,這時(shí)共享的資源不在是同步的了。
[0062] 5)SKCR(Shrink Critical Region):縮小臨界區(qū),將臨界區(qū)的代碼移動到非臨界 區(qū),會引發(fā)數(shù)據(jù)競爭。
[0063] 6)ASTK(Add Static Keyword to Method):添加 Static關(guān)鍵詞,在一個(gè)同步方法 中使用static關(guān)鍵詞表示這個(gè)類對象不是一個(gè)實(shí)例對象,如果將一個(gè)非靜態(tài)同步方法變?yōu)?靜態(tài)同步方法就會使之變?yōu)閷?shí)例對象,引起錯誤的鎖故障。
[0064] 7)RSTK(Remove Static Keyword to Method):移除靜態(tài)方法中的static關(guān)鍵詞。
[0065] 8)RSB(Remove Synchronized Bolock):移除同步塊,引起程序缺失必要的鎖,從 而導(dǎo)致同步錯誤。。
[0066] 9)MSL(Modify Synchronized Location):改變同步塊的位置,使未被初始化完成 的對象被引用,可以導(dǎo)致雙重驗(yàn)證的故障。
[0067] 10)MXT(Modify Method-X Time):作用于wait()、sleep()和 join()方法,改變這 些方法包含的時(shí)間參數(shù),該變異算子使用相同類型不同值替換了時(shí)間參數(shù),使線程等待的 時(shí)間延長或是縮短,從而改變了線程等待的時(shí)間。
[0068] 11)RTXC(Remove Thread Method-X Call):將wait()、join()、sleep()、yield()、 11〇1^€7()和11〇1^€7411()方法調(diào)用移除,移除¥3;[1:()方法可以引起可能的沖突,移除」0;[11() 和sleepO方法能夠引起sleepO故障。
[0069] 12)RJS(Replace Join()with Sleep()):將join()方法替換為sleepO方法。
[0070] 13)RCXC(Remove Concurrency Mechanism Method-X Call):將以下并行機(jī)制移 除:Locks(lock()Nunlock()),Condition(signal()NsignalAll()),Semaphore(acquire ()、release()),Latch(countDown()),ExecutorService(submit()),在該語義變異算子的 作用下,會導(dǎo)致臨界區(qū)缺失故障。
[0071] 14)RFU(Remove Finally Around Unlock):將unlock周圍的finally語句移除, finally保證了鎖最后被釋放,如果該語句被移除,那么發(fā)生異常的時(shí)候不能保證鎖被最終 釋放,會導(dǎo)致臨界資源缺失的故障。
[0072] 15)ASK/RSK(Add/Remove Synchronized Keyword from Method):添加/移除方法 中的Synchronized關(guān)鍵詞,如果該方法中存在臨界區(qū),則ASK會引發(fā)死鎖故障。而RSK則是程 序員經(jīng)常會犯的錯誤,可能會引發(fā)鎖缺失的故障。
[0073] 16)EXCR(Expand Critical Region):擴(kuò)展臨界區(qū),將非臨界區(qū)的代碼添加到臨界 區(qū)中,當(dāng)另一個(gè)臨界區(qū)也包含這些代碼時(shí),會引發(fā)死鎖。
[0074] 17)RNA(Replace NotifyAll ()with Notify()):將notifyAll ()方法替換為 notifyO 方法。
[0075] 18)MSF(Modify Semaphore Fairness):改變信號量的公平性,信號量維護(hù)了進(jìn)入 資源的許可集合,在信號量的構(gòu)造函數(shù)中有一個(gè)可選的Boolean參數(shù),當(dāng)這個(gè)參數(shù)設(shè)為 false時(shí)允許不公平地獲得許可。MSF是將該參數(shù)的true值替換為false或者false替換為 true。
[0076] 19 )MXC (Mod i fy Concurrency Mechani sm-X Count):作用于并發(fā)機(jī)制: Semaphores、Latches 和 Barriers,改變其使用數(shù)量。
[0077] 20)MBR(Modify Barrier Runnable Parameter):改變CyclicBarrier類中構(gòu)造函 數(shù)中runnable參數(shù),這個(gè)參數(shù)是在所有的線程完成并且到達(dá)這個(gè)barrier時(shí)發(fā)生的。如果這 個(gè)可執(zhí)行線程參數(shù)存在的話將它移除。
[0078]本發(fā)明使用了基于Python語言結(jié)合自然語言處理和文本信息匹配的方法,對源程 序進(jìn)行基于特定故障場景的語義變異,生成相對應(yīng)的語義變異體。
[0079] 2、生成初始測試用例集
[0080]將基于混合執(zhí)行的測試用例生成方法作用于生成的語義變異體,本發(fā)明采用基于 混合執(zhí)行的測試用例自動化生成工具jCUTE作用于源程序和語義變異體生成初始測試用例 集。具體做法是將具體執(zhí)行和符號執(zhí)行相結(jié)合,使用變量符號代替具體的用例輸入執(zhí)行程 序,得到程序路徑約束的符號表達(dá)式,然后對符號表達(dá)式進(jìn)行求解,以得到能夠執(zhí)行指定程 序路徑的具體輸入值。然后用一個(gè)隨機(jī)給定的輸入(可以為空值)將程序啟動,然后跟蹤程 序的執(zhí)行路徑,生成該輸入數(shù)據(jù)的條件約束表達(dá)式。再對該約束表達(dá)式進(jìn)行約束求解得到 新的輸入數(shù)據(jù),新輸入數(shù)據(jù)是原來輸入數(shù)據(jù)的反例,最后再用該新測試用例跟蹤執(zhí)行路徑 進(jìn)行測試,一直重復(fù)執(zhí)行這個(gè)迭代過程直到所有的路徑都執(zhí)行完畢或者消耗完規(guī)定的時(shí) 間。這些初始測試用例集基本覆蓋源程序和每個(gè)變異體程序所有可達(dá)路徑。
[0081 ] 使用jCUTE,只需要基本的Java運(yùn)行環(huán)境,在系統(tǒng)變量中加入jCUTE的bin目錄即 可,無需其它配置。具體的,使用"jcutec"命令對源程序進(jìn)行插粧和編譯,生成.class文件, 然后使用"jcute"命令對被插粧和編譯過的可執(zhí)行中間程序進(jìn)行混合執(zhí)行,生成相對應(yīng)的 測試用例。
[0082] 3、收集變異體執(zhí)行信息
[0083]以使用j CUTE生成的初始測試用例集作為輸入,使用程序驗(yàn)證工具JPF (JavaPathFinder)執(zhí)行所有的語義變異體,檢測程序執(zhí)行時(shí)的可能發(fā)生的故障和狀態(tài)信 息。JPF基于形式化的分析與驗(yàn)證技術(shù),即模型檢測技術(shù)。其基本思想是:將要分析的系統(tǒng)抽 象表示為狀態(tài)迀移圖,模態(tài)和時(shí)序邏輯公式Φ表示所要檢查系統(tǒng)的性質(zhì),系統(tǒng)是否具有所要 求的性質(zhì)就歸結(jié)為Sl-φ是否成立。在JPF模型檢測工具中,Java的字節(jié)碼文件為被驗(yàn)證的對 象,通過JPF內(nèi)核的搜索機(jī)制,從被驗(yàn)證對象中搜索出與原工具系統(tǒng)等價(jià)的部分狀態(tài),交給 Java虛擬機(jī)檢測。在JPF中自定義的Java虛擬機(jī),可以用來執(zhí)行普通的Java字節(jié)碼,通過存 儲、匹配和恢復(fù)程序狀態(tài),JPF可以系統(tǒng)地遍歷所有的程序狀態(tài),從而查找出軟件中的缺陷。 用戶需要提供可執(zhí)行的Java字節(jié)碼以及一個(gè)配置文件用來指定需要驗(yàn)證的屬性。JPF返回 一個(gè)報(bào)告,記錄下所需驗(yàn)證的屬性是否被滿足從而進(jìn)行進(jìn)一步的分析,對不符合系統(tǒng)性質(zhì) 的檢測結(jié)果,JPF將在驗(yàn)證報(bào)告中顯示錯誤路徑及性質(zhì)違例。
[0084]本發(fā)明使用Python腳本實(shí)現(xiàn)了全過程的自動化,執(zhí)行結(jié)束后產(chǎn)生執(zhí)行結(jié)果及執(zhí)行 信息統(tǒng)計(jì)文件,該文件記錄了執(zhí)行變異體數(shù)量、測試用例數(shù)量、執(zhí)行消耗時(shí)間、消耗內(nèi)存大 小以及有無錯誤發(fā)生等信息。其中,執(zhí)行變異體總數(shù)量記為T m,變異體執(zhí)行消耗時(shí)間記為?η, 殺死變異體總數(shù)量記為Km,測試用例總量記為η,程序故障總數(shù)記為m。
[0085] 4、優(yōu)化測試用例集
[0086]基于變異體執(zhí)行結(jié)果和狀態(tài)信息,制定測試用例集的優(yōu)化策略。
[0087] (1)MS優(yōu)化,即將測試用例按照變異評分降序排列。其中,變異評分是衡量一個(gè)測 試用例發(fā)現(xiàn)程序語義故障的能力的大小,隨著分值的增大,單個(gè)測試用例發(fā)現(xiàn)錯誤的能力 也就越大,定義為:
[0089] 1為殺死變異體的個(gè)數(shù),Tm為變異體總數(shù),Em為等價(jià)變異體個(gè)數(shù)。
[0090] (2)AC優(yōu)化,即將測試用例按照平均時(shí)間消耗升序排列。其中,平均時(shí)間消耗是指 單個(gè)測試用例執(zhí)行變異體的平均時(shí)間消耗。該指標(biāo)表示測試用例執(zhí)行時(shí)的時(shí)間消耗,在變 異評分相等的情況下,時(shí)間消耗越低,優(yōu)先級越高,定義為:
[0092] tn為單個(gè)測試用例執(zhí)行一個(gè)變異體的時(shí)間消耗,1"為變異體總數(shù)。
[0093] 以初始測試用例集作用下的語義變異體執(zhí)行結(jié)果和狀態(tài)信息作為輸入,首先執(zhí)行 MS優(yōu)化,再對結(jié)果執(zhí)行AC優(yōu)化,最后得到候選的測試用例排序。使用ΑΡΠ )評估標(biāo)準(zhǔn)評估產(chǎn)生 的候選的測試用例集排序,APFD(Average of the Percentage of Faults Detected),即 故障檢測平均百分比,定義為:
[0095]其中η是測試用例的數(shù)量,m表示程序中錯誤的個(gè)數(shù),TFi是第一個(gè)檢測到故障的測 試用例的位置。APFD越大,測試用例集發(fā)現(xiàn)錯誤的速度越快,這樣的測試用例序列就越好。 [0096]為了驗(yàn)證本發(fā)明提出方法的效果,本發(fā)明采用了 7個(gè)實(shí)驗(yàn)程序進(jìn)行了驗(yàn)證。其中5 個(gè)小程序(六;[1'1;[116、4。。011111:、1^111^(11^81:、0;[11;[叫?11;[和1]113〇1^6(11'代6)包含了可以體現(xiàn) Java并行設(shè)計(jì)理念的多個(gè)類,雖然小卻在運(yùn)行時(shí)可以產(chǎn)生很多個(gè)線程,充分利用了 Java的 并行機(jī)制,這些小程序也是并行程序測試中經(jīng)常被優(yōu)先使用的實(shí)驗(yàn)程序。另外兩個(gè)實(shí)驗(yàn)程 序RayTracer和Mo IDyn是來自英國愛丁堡大學(xué)并行計(jì)算中心(Edinburgh Parallel Computing Centre)開發(fā)的標(biāo)準(zhǔn)測試集(Java Grande multi-thread benchmark suite), 是非常著名的并行程序標(biāo)準(zhǔn)測試集。表1列出了這些實(shí)驗(yàn)程序的詳細(xì)信息,其中包括代碼規(guī) 模和產(chǎn)生變異體的數(shù)量。
[0097] 表1實(shí)驗(yàn)程序
[0099]本發(fā)明首先對個(gè)實(shí)驗(yàn)程序進(jìn)行語義變異,獲得各實(shí)驗(yàn)程序的語義變異體;然后使 用基于混合執(zhí)行的方法自動生成7個(gè)實(shí)驗(yàn)程序的初始測試用例集。表2列出了各實(shí)驗(yàn)程序?qū)?應(yīng)的變異體數(shù)量和生成的初始測試用例的數(shù)量,在此過程中我們剔除了極其少量的垃圾數(shù) 據(jù)。
[0100]表2初始測試用例集
[0102] 基于上述實(shí)驗(yàn)結(jié)果,使用初始測試用例集執(zhí)行各程序語義變異體,然后再使用故 障檢測方法對初始測試用例集進(jìn)行故障分析,計(jì)算得到每個(gè)測試用例集的變異評分和平均 消耗。最后使用測試用例優(yōu)化策略對初始測試用例集進(jìn)行優(yōu)化,得到最終的優(yōu)化序列。表3 給出了 7個(gè)實(shí)驗(yàn)程序?qū)?yīng)的最終實(shí)驗(yàn)結(jié)果。
[0103] 表3 APFD值比較
[0105]表3分別記錄了生成的測試用例集在最優(yōu)排序和最差排序下的平均消耗和APFD 值,由表可知,在本發(fā)明提出的測試用例優(yōu)化策略的作用下,對于同一個(gè)程序的相同的測試 用例集,優(yōu)化后的測試用例排序APro值高于在最差排序下的APro值,說明了優(yōu)化后的測試 用例排序能夠更快的發(fā)現(xiàn)程序故障,平均消耗時(shí)間也較少。另外,實(shí)驗(yàn)發(fā)現(xiàn)程序的規(guī)模越 大,則最優(yōu)排序和最差排序所表現(xiàn)出發(fā)現(xiàn)故障的能力差異也就越大,說明本發(fā)明提出的基 于語義變異算子的測試用例生成和優(yōu)化方法非常適合大型的并行程序。因此,發(fā)明提出的 測試用例生成和優(yōu)化方法對于并行程序是非常有效的,生成的測試用例可快速有效的檢測 典型的并行故障,并且盡可能的消耗更少的時(shí)間和資源。
[0106]附圖2-7是每個(gè)實(shí)驗(yàn)程序分別對應(yīng)的實(shí)驗(yàn)結(jié)果圖示,其中深色線代表測試用例最 差排序,淺色線線代表測試用例最優(yōu)排序,縱坐標(biāo)表示執(zhí)行到當(dāng)前測試用例所殺死變異體 的比例,橫坐標(biāo)為執(zhí)行過的測試用例總數(shù)量。由圖可知,在測試用例最優(yōu)排序下往往執(zhí)行了 少量的測試用例就可以殺死所有的變異體,而在測試用例最差排序下則需要執(zhí)行更多的測 試用例才能殺死所有的變異體,這就表明本發(fā)明提出的方法生成的測試用例往往能夠發(fā)現(xiàn) 更多的程序故障。
【主權(quán)項(xiàng)】
1. 一種基于語義變異算子的測試用例生成和優(yōu)化方法,其特征在于步驟如下: 步驟1:將被測源程序作為輸入,將語義變異算子作用于源程序,生成相對應(yīng)的語義變 異體; 步驟2:使用基于混合執(zhí)行的測試用例自動化生成工具jCUTE中的jcutec命令對語義變 異體進(jìn)行插粧和編譯,生成.class文件,然后使用jcute命令對.class文件進(jìn)行混合執(zhí)行, 生成與語義變異體相對應(yīng)的初始測試用例; 步驟3:將每個(gè)初始測試用例作為輸入,使用程序驗(yàn)證工具Java PathFinder執(zhí)行所有 的語義變異體,得到每個(gè)初始測試用例相對應(yīng)的執(zhí)行結(jié)果:產(chǎn)生變異體總數(shù)量!^,單個(gè)測試 用例執(zhí)行一個(gè)變異體的時(shí)間消耗tn,殺死變異體總數(shù)量K m,等價(jià)變異體個(gè)數(shù)Em; 步驟4:依據(jù)執(zhí)行結(jié)果對初始測試用例先進(jìn)行MS優(yōu)化,再進(jìn)行AC優(yōu)化,得到優(yōu)化的測試 用例排序: 所述的MS優(yōu)化,即將測試用例按照變異評分降序排列,定義為:其中,Km為殺死變異體總數(shù)量,Tm為產(chǎn)生變異體總數(shù)量,Em為等價(jià)變異體個(gè)數(shù); 所述的AC優(yōu)化,即將測試用例按照平均時(shí)間消耗升序排列,定義為:其中,tn為單個(gè)測試用例執(zhí)行一個(gè)變異體的時(shí)間消耗,1?為執(zhí)行變異體總數(shù)量。2. 根據(jù)權(quán)利要求1所述的一種基于語義變異算子的測試用例生成和優(yōu)化方法,其特征 在于所述步驟1中的語義變異算子包括以下20種: 1. RVK:移除volatile關(guān)鍵字:將volatile移除后,變量會被線程保存在本地的內(nèi)存空 間中,而并非直接在主存中進(jìn)行讀寫,最終導(dǎo)致數(shù)據(jù)讀寫的不一致; 2. SPCR:分割臨界區(qū),將一個(gè)臨界區(qū)分割為兩個(gè)臨界區(qū),每個(gè)臨界區(qū)中的代碼都仍然是 受保護(hù)的,但是原臨界區(qū)的代碼集合會改變屬性; 3. MSBP:SynChr〇niZaed同步塊的參數(shù)通常有this關(guān)鍵字或相關(guān)對象,該變異算子是將 this關(guān)鍵字或相關(guān)對象替換; 4. SHCR:移動臨界區(qū),將臨界區(qū)上移或下移可能會引起沖突故障,這時(shí)共享的資源不在 是同步的了; 5. SKCR:縮小臨界區(qū),將臨界區(qū)的代碼移動到非臨界區(qū),會引發(fā)數(shù)據(jù)競爭; 6. ASTK:添加 Static關(guān)鍵詞,在一個(gè)同步方法中使用static關(guān)鍵詞表示這個(gè)類對象不 是一個(gè)實(shí)例對象,如果將一個(gè)非靜態(tài)同步方法變?yōu)殪o態(tài)同步方法就會使之變?yōu)閷?shí)例對象, 引起錯誤的鎖故障; 7. RSTK:移除靜態(tài)方法中的static關(guān)鍵詞; 8. RSB:移除同步塊,引起程序缺失必要的鎖,從而導(dǎo)致同步錯誤; 9. MSL:改變同步塊的位置,使未被初始化完成的對象被引用,可以導(dǎo)致雙重驗(yàn)證的故 障; 10. MXT:作用于wai t ()、s 1 eep ()和j〇iη ()方法,改變這些方法包含的時(shí)間參數(shù),該變異 算子使用相同類型不同值替換了時(shí)間參數(shù),使線程等待的時(shí)間延長或是縮短,從而改變了 線程等待的時(shí)間; 11. RTXC:將wait()、join()、sleep()、yield()、notify()和notifyAll()方法調(diào)用移 除,移除wait()方法可以引起可能的沖突,移除join〇和sleep()方法能夠引起sleep()故 障; 12. RJS:將join〇方法替換為sleepO方法; 13 )RCXC:將以下并行機(jī)制移除:Locks(lock()、un lock()),Condi tion( signal ()、 signalAll()),Semaphore(acquire()、release()),Latch(countDown()), ExecutorService(submit()),在該語義變異算子的作用下,會導(dǎo)致臨界區(qū)缺失故障; 14. RFU:將unlock周圍的f inal ly語句移除,f inal ly保證了鎖最后被釋放,如果該語句 被移除,那么發(fā)生異常的時(shí)候不能保證鎖被最終釋放,會導(dǎo)致臨界資源缺失的故障; 15. ASK/RSK:添加/移除方法中的Synchronized關(guān)鍵詞,如果該方法中存在臨界區(qū),則 ASK會引發(fā)死鎖故障,而RSK則是程序員經(jīng)常會犯的錯誤,可能會引發(fā)鎖缺失的故障; 16. EXCR:擴(kuò)展臨界區(qū),將非臨界區(qū)的代碼添加到臨界區(qū)中,當(dāng)另一個(gè)臨界區(qū)也包含這 些代碼時(shí),會引發(fā)死鎖; 17) 1?嫩:將11〇1^€7411()方法替換為11〇1^€7()方法; 18. MSF:改變信號量的公平性,信號量維護(hù)了進(jìn)入資源的許可集合,在信號量的構(gòu)造函 數(shù)中有一個(gè)可選的Boolean參數(shù),當(dāng)這個(gè)參數(shù)設(shè)為false時(shí)允許不公平地獲得許可,MSF是將 該參數(shù)的true值替換為false或者false替換為true; 19 )MXC:作用于并發(fā)機(jī)制:Semaphores、Latches和Barriers,改變其使用數(shù)量; 20)MBR:改變CyclicBarrier類中構(gòu)造函數(shù)中runnable參數(shù),這個(gè)參數(shù)是在所有的線程 完成并且到達(dá)這個(gè)barrier時(shí)發(fā)生的,如果這個(gè)可執(zhí)行線程參數(shù)存在的話將它移除。3. -種對權(quán)利要求1所述的優(yōu)化測試用例排序進(jìn)行評估的方法,其特征在于使用APFD 評估標(biāo)準(zhǔn)對候選的測試用例集排序進(jìn)行評估:所述的APFD為故障檢測平均百分比,定義為:其中,η是測試用例的數(shù)量,m表示程序中錯誤的個(gè)數(shù),1巧是第一個(gè)檢測到故障的測試用 例的位置;APFD越大,測試用例集發(fā)現(xiàn)錯誤的速度越快,這樣的測試用例序列就越好。
【文檔編號】G06F11/36GK105868116SQ201610234663
【公開日】2016年8月17日
【申請日】2016年4月15日
【發(fā)明人】鄭煒, 王育, 楊喜兵, 吳瀟雪
【申請人】西北工業(yè)大學(xué)