黃華俊,吳海濤,高建華,黃子杰
(上海師范大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù),上海 200234)
軟件測(cè)試是保障軟件質(zhì)量的重要手段,通過(guò)發(fā)現(xiàn)軟件缺陷,軟件測(cè)試能確保生產(chǎn)代碼在復(fù)雜使用條件下的健壯性[1,2].大型商業(yè)軟件中包含數(shù)量龐大的測(cè)試代碼[3],維護(hù)工作成本高昂,需要理論和自動(dòng)化工具的支持.
測(cè)試驅(qū)動(dòng)開發(fā)(TDD)[4]是一種敏捷開發(fā)方法,它提倡在實(shí)現(xiàn)業(yè)務(wù)代碼前編寫對(duì)應(yīng)的測(cè)試用例,以保障代碼組件的設(shè)計(jì)符合預(yù)期.作為測(cè)試驅(qū)動(dòng)開發(fā)的重要組成部分,自動(dòng)化測(cè)試可以在保障軟件系統(tǒng)質(zhì)量的前提下,高效地避免開發(fā)過(guò)程中出現(xiàn)功能回退和設(shè)計(jì)錯(cuò)誤等問(wèn)題,從而極大地提高了開發(fā)效率[1,2,5].
自動(dòng)化測(cè)試代碼是軟件系統(tǒng)的重要組成部分,編寫和維護(hù)具備和生產(chǎn)代碼類似的挑戰(zhàn)性[6].然而,研究發(fā)現(xiàn)開發(fā)人員傾向于忽視測(cè)試代碼的重要性.他們認(rèn)為,相比生產(chǎn)代碼,編寫和維護(hù)測(cè)試代碼是一種成本高于回報(bào)的負(fù)擔(dān).因此,測(cè)試代碼缺乏嚴(yán)謹(jǐn)?shù)闹貥?gòu)計(jì)劃[7],其質(zhì)量普遍低于生產(chǎn)代碼[8-11].提升測(cè)試代碼質(zhì)量的實(shí)際意義主要基于主觀經(jīng)驗(yàn)得出,仍未被量化研究充分驗(yàn)證和討論,導(dǎo)致軟件測(cè)試的意義未被充分重視.因此,選取一個(gè)可量化的角度分析測(cè)試質(zhì)量提升的意義是迫在眉睫的.
代碼異味(Code Smell)是代碼中潛在的不良設(shè)計(jì)和不良實(shí)現(xiàn)[12],它可以衡量生產(chǎn)代碼的質(zhì)量.測(cè)試異味(Test Code Smell,簡(jiǎn)稱Test Smell)是代碼異味在軟件測(cè)試中的衍生概念[7],它是軟件測(cè)試中存在不良設(shè)計(jì)和不良實(shí)現(xiàn)的征兆,使用測(cè)試異味度量可以量化測(cè)試代碼的質(zhì)量.
目前,已有工作討論了測(cè)試異味的量化檢測(cè)方式和部分性質(zhì)[13-15],但缺乏從異味重構(gòu)的視角探討其對(duì)代碼質(zhì)量的影響,也未能指出對(duì)代碼質(zhì)量提升最為有效的測(cè)試重構(gòu)操作[14,15],使開發(fā)者難以權(quán)衡消除代碼異味的代價(jià)和收益.
本文檢測(cè)了6個(gè)開源軟件的93個(gè)發(fā)布版本,涉及5種測(cè)試異味,包括神秘客人(Mystery Guest)、資源樂觀(Resource Optimism)、餓漢測(cè)試(Eager Test)、斷言輪盤(Assertion Roulette)和敏感恒等(Sensitive Equality).對(duì)于軟件歷史版本中的測(cè)試異味消除操作,本文使用SZZ算法量化了測(cè)試代碼及其關(guān)聯(lián)生產(chǎn)代碼(簡(jiǎn)稱測(cè)試及生產(chǎn)代碼)的缺陷傾向,并利用相對(duì)風(fēng)險(xiǎn)RR指標(biāo)分析缺陷傾向數(shù)據(jù),計(jì)算測(cè)試及生產(chǎn)代碼在異味消除前后存在缺陷傾向的可能性,以量化消除異味對(duì)代碼質(zhì)量的影響.
本文的主要貢獻(xiàn)為:
1)通過(guò)對(duì)6個(gè)開源軟件系統(tǒng)中的5種測(cè)試異味進(jìn)行分析和探討,發(fā)現(xiàn)消除測(cè)試異味前,測(cè)試代碼存在缺陷傾向的概率是消除異味后的一倍,驗(yàn)證了消除測(cè)試異味可以顯著提升測(cè)試代碼質(zhì)量;
2)對(duì)比分析了測(cè)試異味消除前后生產(chǎn)代碼的缺陷傾向變化,得出消除測(cè)試異味能使生產(chǎn)代碼存在缺陷傾向的概率減少59%;
3)分別對(duì)5種測(cè)試異味分組研究,發(fā)現(xiàn)消除餓漢測(cè)試異味可以最顯著地提升生產(chǎn)代碼的質(zhì)量.
本文的章節(jié)安排如下:第2節(jié)介紹測(cè)試異味的相關(guān)術(shù)語(yǔ);第3節(jié)詳細(xì)闡述所提出的方法流程;第4節(jié)設(shè)計(jì)實(shí)驗(yàn)并對(duì)結(jié)果進(jìn)行分析;第5節(jié)總結(jié)本文內(nèi)容并討論將來(lái)的工作.
參考代碼異味的研究成果,Van Deurson等人[7]定義并提出了11種測(cè)試異味及其重構(gòu)方法.Meszaros等人[16]基于Van Deurson等人的成果,針對(duì)他們?cè)陂_發(fā)過(guò)程中遇到的實(shí)際問(wèn)題,擴(kuò)充了另外18種測(cè)試異味.在18種測(cè)試異味的基礎(chǔ)上,Tufano等人[14]調(diào)查了開源軟件中5個(gè)常見測(cè)試異味即斷言輪盤、餓漢測(cè)試、通用固件(General Fixture)、神秘客人和敏感恒等的性質(zhì).
表1給出了本文所涉及的測(cè)試異味,它們?cè)从赩an Deursen等人[7]定義的異味目錄,包括神秘客人、資源樂觀、餓漢測(cè)試、斷言輪盤和敏感恒等.選擇以上5種測(cè)試異味的原因包括:
表1 測(cè)試異味及其描述Table 1 Description of test smells
1)它們常見于相關(guān)研究[17]和開源軟件系統(tǒng)(OSS)項(xiàng)目中[15];
2)這些測(cè)試異味的產(chǎn)生原因不同,不存在顯著的共現(xiàn)性,且與測(cè)試代碼的不同特征有關(guān).
在研究測(cè)試異味自動(dòng)化檢測(cè)工具的相關(guān)文獻(xiàn)中,最為常見的是Bavota等人[15]實(shí)現(xiàn)的異味檢測(cè)工具,研究指出其精確率能達(dá)到88%,召回率能達(dá)到100%,但該工具非開源軟件.因此,本文選擇開源的tsDetect異味檢測(cè)工具作為替代,在檢測(cè)測(cè)試異味時(shí),它能夠達(dá)到至少85%的準(zhǔn)確率和90%的召回率,其F-Score為96.5%[18].相較于Bavota等人的工具,tsDetect更易獲取和驗(yàn)證,且與Bavota等人的工具有著相仿的精確率與召回率.
Palomba等人[19]調(diào)查了EvoSuite自動(dòng)生成的測(cè)試代碼,發(fā)現(xiàn)自動(dòng)測(cè)試生成工具沒有考慮生成代碼的質(zhì)量,斷言輪盤和餓漢測(cè)試的問(wèn)題在生成測(cè)試代碼中很普遍.
Tahir等人[20]調(diào)查了測(cè)試異味和類的復(fù)雜度、內(nèi)聚性度量的關(guān)系,研究發(fā)現(xiàn)復(fù)雜性度量,即環(huán)路復(fù)雜性和加權(quán)方法個(gè)數(shù),是存在測(cè)試異味的強(qiáng)烈信號(hào).
Bavota等人[15]進(jìn)行了第一次大規(guī)模的研究實(shí)驗(yàn).研究發(fā)現(xiàn),測(cè)試異味對(duì)測(cè)試代碼的可理解性和可維護(hù)性會(huì)產(chǎn)生負(fù)面影響,軟件規(guī)模越大,測(cè)試異味的影響越嚴(yán)重,且敏感恒等和神秘客人的強(qiáng)度同軟件系統(tǒng)的壽命正相關(guān).然而,測(cè)試異味對(duì)代碼質(zhì)量影響研究仍不夠充分.Spadini等人[17]發(fā)現(xiàn)測(cè)試異味中的測(cè)試代碼會(huì)使關(guān)聯(lián)生產(chǎn)代碼產(chǎn)生更高的易錯(cuò)性,但并未論證消除測(cè)試代碼異味帶來(lái)的影響.
測(cè)試異味使生產(chǎn)代碼更易錯(cuò),但不當(dāng)?shù)闹貥?gòu)可能事倍功半.由于重構(gòu)測(cè)試代碼異味的價(jià)值不明,開發(fā)人員通常難以確定是否應(yīng)該進(jìn)行重構(gòu),這一現(xiàn)狀對(duì)測(cè)試質(zhì)量產(chǎn)生長(zhǎng)期的負(fù)面影響.Hasanain等人[21]發(fā)現(xiàn),愛立信的工業(yè)測(cè)試代碼中普遍存在代碼拷貝問(wèn)題,且測(cè)試規(guī)模越大,代碼拷貝越多.研究還揭示了測(cè)試代碼拷貝的生成機(jī)理,因?yàn)闇y(cè)試代碼規(guī)模龐大、邏輯復(fù)雜且長(zhǎng)期疏于維護(hù),其可理解性極差.與其重構(gòu)一個(gè)測(cè)試方法,不如重新實(shí)現(xiàn),然而,重新實(shí)現(xiàn)的測(cè)試方法無(wú)法避免的再一次引入了代碼拷貝問(wèn)題.因此,明確消除測(cè)試異味給代碼質(zhì)量帶來(lái)的收益,是確定測(cè)試異味重構(gòu)價(jià)值的必要條件.
本文分析測(cè)試異味消前后測(cè)試及生產(chǎn)代碼的缺陷傾向變化,圖1給出了分析過(guò)程,包括以下3個(gè)步驟:
圖1 實(shí)驗(yàn)步驟Fig.1 Experimental steps
1)數(shù)據(jù)預(yù)處理.本文通過(guò)挖掘開源項(xiàng)目中各個(gè)歷史發(fā)布版本的測(cè)試代碼,對(duì)其中存在測(cè)試異味,并在而后的歷史版本中被消除的測(cè)試代碼進(jìn)行收錄,以獲取測(cè)試代碼數(shù)據(jù)集.對(duì)測(cè)試代碼數(shù)據(jù)集中的測(cè)試代碼,通過(guò)測(cè)試代碼組件的命名特征,來(lái)獲取相關(guān)聯(lián)的待測(cè)生產(chǎn)代碼的數(shù)據(jù)集;
2)采集代碼的缺陷傾向.將缺陷傾向作為代碼質(zhì)量的一般度量,使用挖掘項(xiàng)目歷史提交記錄工具采集相關(guān)的所有修復(fù)bug的代碼提交(bug-fixing commits),并通過(guò)SZZ算法來(lái)追溯修復(fù)bug的代碼提交的源頭,即引入bug的代碼提交;
3)計(jì)算相對(duì)風(fēng)險(xiǎn)RR.采用相對(duì)風(fēng)險(xiǎn)RR指標(biāo)來(lái)分析異味消除前后缺陷傾向的變化情況.
為了獲取研究所需的數(shù)據(jù)集,本文對(duì)采集到的開源數(shù)據(jù)進(jìn)行了加工,其過(guò)程如圖2所示.
圖2 測(cè)試及生產(chǎn)代碼數(shù)據(jù)預(yù)處理過(guò)程Fig.2 Test and production code data preprocessing process
收集數(shù)據(jù)集中涉及異味消除的測(cè)試代碼需要3個(gè)步驟:
首先,收集項(xiàng)目P中的測(cè)試類集合C.根據(jù)相關(guān)文獻(xiàn)[14,22],當(dāng)類名以“Test”或“Tests”結(jié)尾時(shí),可判定它是測(cè)試類.
其次,使用tsDetect檢測(cè)C中的異味,對(duì)于C中的任意元素ci,可獲得ci在P全部發(fā)布版本1至m中的異味分布情況文件集合Fci= {fileci,1,fileci,2,…,fileci,m},其中列出了每個(gè)測(cè)試類中5種測(cè)試異味的分布情況.
最后,本文實(shí)現(xiàn)了對(duì)測(cè)試異味消除過(guò)程的捕獲工具.如圖3所示,對(duì)于任意的Fci,該工具可對(duì)比和記錄fileci,1至fileci,i之間每種異味狀態(tài)的變化情況,并收集測(cè)試異味被消除時(shí)的發(fā)布版本號(hào).其工作原理如下:
1)當(dāng)測(cè)試類中的其中一種異味滿足:在{fileci,1,fileci,2,…,fileci,n}中的該種異味狀態(tài)為“true”,而在 {fileci,n+1,fileci,n+2,…,fileci,m}中為“false”時(shí),分別分析其他4種異味的分布變化情況;
2)若其他四種異味在{fileci,1,fileci,2,…,fileci,m}中異味狀態(tài)全為“true”或全為“false”,則記錄該異味類型和fileci,n+1對(duì)應(yīng)的發(fā)布版本號(hào).
圖3 測(cè)試異味消除過(guò)程捕獲工具的輸出示例Fig.3 Output example of test smell elimination process capture tool
對(duì)于涉及異味消除的測(cè)試代碼,本文利用一種基于約定俗成的命名方式追溯生產(chǎn)代碼,以獲取與測(cè)試代碼對(duì)應(yīng)的生產(chǎn)代碼數(shù)據(jù)集,即通過(guò)從JUnit測(cè)試類的類名中刪除字符串“Test”或“Tests”來(lái)識(shí)別被測(cè)試的生產(chǎn)代碼類.Van Rompaey和Demeyer[23]證明該技術(shù)與其他可跟蹤性方式(例如,基于切片的方式[24])相比,其準(zhǔn)確性和可伸縮性最優(yōu).
缺陷傾向的量化基于SZZ算法的.缺陷傾向又稱易錯(cuò)性,文件的缺陷傾向是指文件在兩個(gè)版本之間的引入bug的代碼提交.對(duì)于系統(tǒng)的發(fā)布版本集合R= {r1,r2,…,rj}中的任意發(fā)布版本rv,計(jì)算發(fā)布版本rv下某個(gè)文件的缺陷傾向,是在rv的上一個(gè)修訂版本至rv之間進(jìn)行的,這是因?yàn)閷?duì)于修復(fù)文件bug的代碼變更提交,旨在修復(fù)rv與rv之后的修訂版間的bug,而其中的bug是在rv之前引入的.
SZZ算法[25,26]是由Sliwerski、Zimmermann和Zeller提出的,用以追溯引入bug的代碼提交的方法,它依賴于版本控制系統(tǒng)的追溯指令annotate或blame指令[26],追溯指令可以查詢文件的作者、修訂信息、相關(guān)URL和歷史修改記錄,這些信息會(huì)以注釋的形式展示在對(duì)應(yīng)的文件中.SZZ算法計(jì)算類缺陷傾向的思路是:根據(jù)代碼發(fā)生bug時(shí)版本控制系統(tǒng)對(duì)bug所在類的變更記錄,估計(jì)bug被引入的時(shí)刻.
如圖4所示,SZZ的運(yùn)行原理可以理解為四個(gè)步驟:
1)提取更改記錄,以查找修復(fù)bug提交的變更信息;
2)對(duì)比修改前后版本代碼差異,并精確定位涉及的源代碼行;
3)追溯修改后的代碼的上一個(gè)修訂版本代碼提交信息及版本號(hào);
4)輸出代碼提交的ID列表.
對(duì)于發(fā)布版本rv下的任意bugB,識(shí)別修復(fù)B的代碼提交,以確定修復(fù)操作所涉及到的類集合Cfixed= {c1,c2,…,ck}以及類中變更的源代碼行位置集合linecj= {l1,l2,…,li},SZZ算法的工作原理如下:
算法1.SZZ(Sliwerski、Zimmermann and Zeller)算法
輸入:發(fā)布版本rj下任意的B
輸出:引發(fā)B的n個(gè)代碼變更提交
Step 1.對(duì)于修復(fù)B的代碼變更提交,令發(fā)生該操作的修訂版為rv,提取涉及到的類集合Cfixed.
Step 2.對(duì)于其中任意一個(gè)類cj,修復(fù)B時(shí)涉及到cj的源代碼行變更集合linecj,通過(guò)annotate或blame指令操作標(biāo)識(shí)類中每行代碼最后一次更改發(fā)生的時(shí)間,找到linecj中每個(gè)元素lnum對(duì)應(yīng)的上一個(gè)修訂版本rlnum.
Step 3.將rlnum至rv間的所有代碼提交標(biāo)記為引入bug的代碼提交.
Step 4.使用island語(yǔ)法分析器[27]捕獲空白行和只包含注釋的行,輸出引入bug的代碼提交列表和數(shù)量n.
圖4 SZZ算法獲取缺陷傾向工作原理Fig.4 SZZ algorithm obtains the working principleof defect-prone
至此,SZZ算法可以找到引發(fā)B的,所有引入bug的代碼提交的相關(guān)信息,例如代碼提交的ID列表及個(gè)數(shù).針對(duì)rv中所有修復(fù)bug的代碼提交修復(fù)了的bugbugfixed= {bug1,bug2,…,bugb}.
rv缺陷傾向的計(jì)算方式為:對(duì)于bugfixed中的每一個(gè)bug,SZZ算法所獲得的代碼提交ID個(gè)數(shù)的總和.
版本rv下cj缺陷傾向計(jì)算方式為:對(duì)于bugfixed中的每一個(gè)bug涉及到cj的所有引入bug的代碼提交個(gè)數(shù)總和.
相對(duì)風(fēng)險(xiǎn)是暴露組發(fā)生概率與非暴露組發(fā)生概率的比值,即一個(gè)群體暴露在一定風(fēng)險(xiǎn)下,與未暴露在該風(fēng)險(xiǎn)下某事件的比值.在本文中暴露組是測(cè)試異味消除前代碼存在缺陷傾向,非暴露組是測(cè)試異味消除后代碼存在缺陷傾向.RR常被用于前瞻性研究,本文用它衡量測(cè)試異味消除前相較于消除后,代碼具有更多或更少的缺陷傾向可能性.相對(duì)風(fēng)險(xiǎn)RR的計(jì)算公式如(1)所示:
(1)
當(dāng)相對(duì)風(fēng)險(xiǎn)RR等于1時(shí),在兩個(gè)樣本中,事件發(fā)生的可能性相同.RR大于1時(shí),第一個(gè)樣本中更有可能發(fā)生該事件,例如:測(cè)試異味消除前,代碼有缺陷傾向.RR小于1時(shí),第二個(gè)樣本中更有可能發(fā)生該事件,例如:測(cè)試異味消除后,代碼有缺陷傾向.本文采用該方法分析異味消除前后代碼發(fā)生缺陷情況原因有:1)統(tǒng)計(jì)領(lǐng)域報(bào)告的結(jié)果顯示,在進(jìn)行大規(guī)模實(shí)證性研究時(shí),這種方法應(yīng)該是首選[28,29];2)RR相對(duì)風(fēng)險(xiǎn)分析等同于優(yōu)勢(shì)比分析[30],且可解釋性更高[17].
實(shí)驗(yàn)在Windows 10和Java 8環(huán)境下進(jìn)行.對(duì)于tsDetect[18]的有效性,tsDetect工具的開發(fā)團(tuán)隊(duì)進(jìn)行了一次大規(guī)模的手工驗(yàn)證,在此期間,他們?cè)?56個(gè)開源Android應(yīng)用程序中,隨機(jī)選擇測(cè)試文件及其相應(yīng)的生產(chǎn)文件,并邀請(qǐng)了羅切斯特理工學(xué)院軟件工程系的39名研究生和本科生,來(lái)手動(dòng)檢查選出的文件文件是否存在測(cè)試氣味.所有參與者都是自愿參加的,并且熟悉Java編程,和單元測(cè)試.這些參與者在Java開發(fā)方面的經(jīng)驗(yàn)從2到11年不等,其中包括開發(fā)單元測(cè)試的經(jīng)驗(yàn),以此驗(yàn)證了tsDetect能正確識(shí)別測(cè)試代碼異味.
表2 實(shí)驗(yàn)數(shù)據(jù)集Table 2 Experiment dataset
如表2所示,本文參考文獻(xiàn)[17],選擇了其中的6個(gè)規(guī)模不同的開源軟件系統(tǒng)作為測(cè)試數(shù)據(jù)集,所有版本中都有大量的JUnit測(cè)試用例.考慮到次要發(fā)布版本(Minor Releases)之間的變更不顯著且過(guò)于頻繁,本文只考慮每個(gè)系統(tǒng)主要發(fā)布版本(Major Releases).
本文挖掘測(cè)試代碼中的異味,對(duì)比異味在消除前后,測(cè)試代碼以及受測(cè)的生產(chǎn)代碼的缺陷傾向的變化,并根據(jù)結(jié)果評(píng)估測(cè)試異味消除后多大程度的影響軟件的代碼質(zhì)量.實(shí)驗(yàn)回答以下3個(gè)研究問(wèn)題:
RQ1:測(cè)試異味消除前后,測(cè)試代碼的缺陷傾向呈現(xiàn)何種變化?
RQ2:測(cè)試異味消除前后,生產(chǎn)代碼的缺陷傾向呈現(xiàn)何種變化?
RQ3:是否存在影響實(shí)驗(yàn)效度的因素?
1)首先對(duì)開源數(shù)據(jù)進(jìn)行預(yù)處理,獲取所有待研究的測(cè)試類,并將這些測(cè)試類作為測(cè)試異味檢查工具的輸入數(shù)據(jù).
2)對(duì)于每個(gè)測(cè)試類,使用靜態(tài)分析工具tsDetect檢測(cè)每個(gè)發(fā)布版本中測(cè)試代碼的測(cè)試異味,并采用測(cè)試異味消除過(guò)程捕獲工具,收集在版本迭代中測(cè)試異味被消除的測(cè)試代碼,并通過(guò)命名跟蹤技術(shù),找到關(guān)聯(lián)的生產(chǎn)代碼的類,作為生產(chǎn)代碼數(shù)據(jù)集.
3)按照5種測(cè)試異味類型,對(duì)所有的數(shù)據(jù)集進(jìn)行歸類,將其分為5組.
4)確定測(cè)試異味被消除的版本,使用SZZ算法計(jì)算該版本前后,所有主要發(fā)布版本的測(cè)試及生產(chǎn)類的缺陷傾向.本文復(fù)現(xiàn)了SZZ算法,根據(jù)Fischer等人[31]的方法確定提交是否修復(fù)了缺陷,該方法基于版本控制系統(tǒng)在代碼提交時(shí)記錄的消息進(jìn)行分析.如果提交消息與問(wèn)題跟蹤器中存在的問(wèn)題ID匹配,或當(dāng)它包含“bug”,“fix”或“defect”等關(guān)鍵字時(shí),將其視為錯(cuò)誤修復(fù)提交.為獲取錯(cuò)誤修復(fù)提交,本文使用RepoDriller[32]挖掘所有的代碼提交.RepoDriller是一個(gè)用來(lái)幫助研究人員挖掘軟件代碼倉(cāng)庫(kù)以做研究的Java框架.一旦通過(guò)RepoDriller獲取到所有涉及的修復(fù)bug的代碼提交,SZZ算法將通過(guò)Git的blame特性記錄所有可能的引入bug的代碼提交.
5)最后根據(jù)SZZ量化的缺陷傾向,計(jì)算出測(cè)試異味消除前后,代碼有缺陷傾相對(duì)風(fēng)險(xiǎn)RR指數(shù),通過(guò)分析該指數(shù),得出了消除測(cè)試異味對(duì)代碼質(zhì)量的影響.
RQ1:測(cè)試異味消除前后,測(cè)試代碼的缺陷傾向呈現(xiàn)何種變化?
為了回答RQ1,本文從3個(gè)角度分析缺陷傾向呈現(xiàn)何種變化,即:1)整體變化的趨勢(shì);2)測(cè)試異味消除后,測(cè)試代碼存在缺陷傾向的可能性變化多少;3)消除不同種類的測(cè)試異味對(duì)測(cè)試代碼缺陷傾向的影響,分別對(duì)應(yīng)圖5、表3和圖6.
圖5展示了測(cè)試異味消除前后,測(cè)試代碼缺陷傾向數(shù)量分布的對(duì)比.觀察圖5的箱線圖,可以看到,相較消除之前,消除異味之后測(cè)試代碼含有的缺陷傾向數(shù)量顯著減少.箱線圖中也出現(xiàn)了幾個(gè)異常值,如異味消除前一個(gè)測(cè)試類最多含有27個(gè)缺陷傾向,消除之后最多也是27個(gè),這個(gè)結(jié)果是由于測(cè)試異味的特性所導(dǎo)致的.例如:斷言輪盤包括不止一種斷言用來(lái)檢查不同的行為,餓漢測(cè)試需要調(diào)用生產(chǎn)對(duì)象的多個(gè)方法,它們所涉及的文件多消除這些異味往往變更量大,所以統(tǒng)計(jì)含有這些異味的測(cè)試代碼的缺陷傾向數(shù)量時(shí)可能出現(xiàn)異常大的值.這些異味特性的本質(zhì)使得它們難以被開發(fā)人員所理解,進(jìn)而導(dǎo)致開發(fā)人員更容易引入缺陷.
圖5 測(cè)試異味消除前后測(cè)試代碼的缺陷傾向數(shù)量分布對(duì)比Fig.5 Number distribution of defect-proneness in test code before and after test smell removal
表3中統(tǒng)計(jì)了180條測(cè)試異味被消除的記錄,其中暴露組(測(cè)試異味消除前)生產(chǎn)代碼存在缺陷傾向概率為81%,非暴露組(測(cè)試異味消除后)生產(chǎn)代碼存在缺陷傾向概率為36%,RR值為2.26,即消除測(cè)試異味之后,測(cè)試代碼有缺陷傾向的可能性較消除之前減少126%.
表3 測(cè)試異味消除前后測(cè)試代碼有缺陷傾向的相對(duì)風(fēng)險(xiǎn)Table 3 Test smell elimination before and after the test code with defect-prone′RR
圖6展示了按消除異味的種類分成5組的實(shí)驗(yàn)數(shù)據(jù),從圖中觀察的結(jié)果可知測(cè)試異味消除后,測(cè)試代碼的缺陷傾向都趨向減少,表明消除測(cè)試異味對(duì)測(cè)試代碼的質(zhì)量起到提升的作用.其中,敏感恒等(Sensitive Equality)的變化趨勢(shì)非常明顯,造成這一現(xiàn)象的原因可能是數(shù)據(jù)集中軟件壽命較長(zhǎng).Bavota等人[15]研究發(fā)現(xiàn)敏感恒等的強(qiáng)度同軟件系統(tǒng)的壽命呈正相關(guān),本文數(shù)據(jù)集中軟件系統(tǒng)的最早版本發(fā)布時(shí)間可追溯到10至20年前.在這類系統(tǒng)中,一旦該異味被消除,異味消除前后,缺陷傾向的變化會(huì)很大.
利用和RQ1類似的方法,回答RQ2:測(cè)試異味消除后,生產(chǎn)代碼的缺陷傾向呈現(xiàn)何種變化?
圖6 不同種類測(cè)試異味消除前后測(cè)試代碼缺陷傾向數(shù)量分布對(duì)比圖7 測(cè)試異味消除前后生產(chǎn)代碼的缺陷傾向數(shù)量分布對(duì)比Fig.6 Number distribution of defect-proneness in test code beforeand after different kinds of test smell elimination is comparedFig.7 Number distribution of defect-proneness in production code before and after test smell elimination
如圖7的箱線圖,易見測(cè)試異味消除前后,生產(chǎn)代碼中的缺陷傾向數(shù)量下降,表明相較于測(cè)試異味消除后,生產(chǎn)代碼質(zhì)量得到了一定的提升.
據(jù)表4,測(cè)試異味消除前后生產(chǎn)代碼有缺陷傾的相對(duì)風(fēng)險(xiǎn)RR值為1.59,表明消除測(cè)試異味使生產(chǎn)代碼有缺陷的概率降低了59%.
表4 測(cè)試異味消除前后生產(chǎn)代碼有缺陷傾向的相對(duì)風(fēng)險(xiǎn)Table 4 Test smell elimination before and after the production code with defect-prone′RR
圖8描述了5組實(shí)驗(yàn)數(shù)據(jù)集的生產(chǎn)代碼中缺陷傾向數(shù)的分布情況.5種測(cè)試異味消除后,生產(chǎn)代碼的整體缺陷傾向數(shù)量都趨向于減少.相較于其它4種測(cè)試異味,餓漢測(cè)試的減少趨勢(shì)最為顯著.餓漢測(cè)試被消除后,生產(chǎn)代碼缺陷傾向的平均值從7.8降低至2.4,減少了69.2%.餓漢測(cè)試的存在,可能是待測(cè)生產(chǎn)代碼質(zhì)量降低的重要原因.
圖8 不同種類測(cè)試異味消除前后生產(chǎn)代碼缺陷傾向數(shù)量分布對(duì)比Fig.8 Number distribution of defect-proneness in production code before and after different kinds of test smell elimination is compared
對(duì)于RQ3,影響實(shí)驗(yàn)效度的因素有以下幾點(diǎn):
1)不同規(guī)模的軟件系統(tǒng)、不同開發(fā)團(tuán)隊(duì)的代碼風(fēng)格和開發(fā)習(xí)慣,可能造成測(cè)試異味分布不均影響結(jié)論的數(shù)值.
2)本文的結(jié)論基于測(cè)試異味檢測(cè)工具的準(zhǔn)確程度,檢測(cè)工具的質(zhì)量可能影響實(shí)驗(yàn)效度.為了獲得有關(guān)測(cè)試異味的信息,本文使用tsDetect測(cè)試異味檢測(cè)器.盡管此工具精確率能達(dá)到85%以上,且召回率在90%以上,非常之高,但數(shù)據(jù)集中仍然可能存在一些誤報(bào).
3)Fischer等人[31]提出的確定提交是否修復(fù)了bug的方法,它基于版本控制系統(tǒng)在代碼提交時(shí)記錄的消息進(jìn)行分析.這種方法在過(guò)去被廣泛用于識(shí)別bug修復(fù)[34,35],其精確率接近80%[31,33,35],Spadini等人[17]在實(shí)現(xiàn)SZZ算法時(shí)使用的是該方法,并認(rèn)為對(duì)于實(shí)現(xiàn)SZZ算法這種技術(shù)足夠準(zhǔn)確,因此本文也采用了相同的技術(shù).
4)另一個(gè)威脅在于基于命名約定的可追溯性技術(shù),該方法通過(guò)測(cè)試代碼檢測(cè)相關(guān)聯(lián)的生產(chǎn)代碼,但這種關(guān)聯(lián)方式,可能因?yàn)殚_發(fā)人員缺乏經(jīng)驗(yàn)或人為錯(cuò)誤導(dǎo)致結(jié)果的不準(zhǔn)確.這種技術(shù)在相關(guān)研究中被大量采用[13,14,22].Van Rompaey和Demeyer[23]也對(duì)該技術(shù)進(jìn)行了評(píng)估,結(jié)果報(bào)告平均精度為100%,召回率為70%.
5)本文僅討論了Java項(xiàng)目的測(cè)試異味,對(duì)于其它使用弱類型系統(tǒng)的動(dòng)態(tài)語(yǔ)言,例如JavaScript,其測(cè)試異味與代碼質(zhì)量的關(guān)系可能具備不同性質(zhì).
軟件測(cè)試代碼的重要性經(jīng)常被忽視,明確測(cè)試異味對(duì)代碼質(zhì)量的影響,可以降低軟件重構(gòu)和維護(hù)的成本,并提升軟件代碼質(zhì)量.本文使用SZZ算法量化測(cè)試及生產(chǎn)代碼的缺陷傾向,并利用RR相對(duì)風(fēng)險(xiǎn)計(jì)算測(cè)試異味消除前后測(cè)試及生產(chǎn)代碼存在缺陷傾向的可能性,以分析消除測(cè)試異味對(duì)軟件代碼質(zhì)量的影響.本文通過(guò)實(shí)驗(yàn)研究得出以下結(jié)論:
1)消除測(cè)試異味能使測(cè)試代碼的質(zhì)量得到顯著的提升.在測(cè)異味消除之后,測(cè)試代碼存在缺陷傾向的可能性較之前減少約一倍(126%);
2)消除測(cè)試異味,能提升生產(chǎn)代碼的質(zhì)量.消除測(cè)試異味后,生產(chǎn)代碼存在缺陷傾向的概率較之前少59%;
3)相較于其他4種測(cè)試異味,重構(gòu)餓漢測(cè)試對(duì)生產(chǎn)代碼質(zhì)量的提升更大.
后續(xù)工作有三個(gè)方向.其一,本文的研究基于Java項(xiàng)目開展,可以基于其他編程語(yǔ)言的開源項(xiàng)目進(jìn)行研究;其二,本文的研究粒度限制在類級(jí)別,可以進(jìn)一步細(xì)化到方法級(jí)別,以探究開發(fā)人員是在方法級(jí)別進(jìn)行編碼的情況;其三,因?yàn)闇y(cè)試異味的生命周期很長(zhǎng),項(xiàng)目中消除測(cè)試異味的數(shù)據(jù)較少,可以進(jìn)一步對(duì)各種不同規(guī)模的開源項(xiàng)目開展研究.