張小鵬,趙逢禹,劉 亞
(上海理工大學(xué) 光電信息與計算機工程學(xué)院,上海 200093)
在大型軟件項目設(shè)計開發(fā)過程中,代碼評審(Code Review)是發(fā)現(xiàn)代碼缺陷進(jìn)而提高軟件質(zhì)量的重要手段.Bavota等人[1]通過對三個開源系統(tǒng)的探索性研究,旨在調(diào)查代碼評審對代碼缺陷修復(fù)和提交代碼組件質(zhì)量的影響.他們的研究表明手動評審代碼對軟件項目的代碼質(zhì)量有著重大的影響.QT、Android和Open Stack軟件項目為了維護(hù)項目的代碼質(zhì)量,更是保持了一個龐大的代碼評審團(tuán)隊[2].由此可見代碼評審確實能夠更好的保障軟件項目的質(zhì)量.
目前關(guān)于代碼評審的研究主要集中在代碼評審時的責(zé)任分配[3,4]、對軟件項目質(zhì)量的影響[1,2,5]、評審方法研究[6]和自動的推薦代碼評審者等方面.Weiss[7]等人研究發(fā)現(xiàn),針對開源軟件項目中的代碼提交,具有評審者分配問題的代碼提交時間相比沒有分配問題的提交時間平均會多花費6到12天.更重要的是,有些提交的代碼從未收到任何代碼評審意見,也就無法被合并到主代碼庫.由此可以看出,如何為代碼找到合適的評審者對保障軟件系統(tǒng)的質(zhì)量、提高軟件的開發(fā)效率是非常有價值的.
在早期的代碼評審?fù)扑]研究中,McDonald和Ackerman改進(jìn)了基礎(chǔ)的Line 10 Rule評審者推薦算法,使用了三種數(shù)據(jù)來標(biāo)識評審者[8].該算法首先要求所有的評審者都要創(chuàng)建自己的概要文件;然后使用提交日志信息統(tǒng)計每個評審者評審過的模塊總數(shù);最后從問題跟蹤器中為具有代表性的問題描述建立索引.利用這些數(shù)據(jù),可以根據(jù)新提交問題的描述進(jìn)行評審者的推薦.
Balachandran提出了基于修改歷史的評審者推薦算法Review Bot[9].它利用代碼層次的修改歷史來推薦評審者.如果一次新提交所涉及的修改代碼擁有修改歷史,Review Bot將會為候選的評審者計算相應(yīng)修改代碼的修改次數(shù).
Thongtanunam等人提出了利用文件路徑相似性推薦代碼評審者的FPS(File Path Similarity)算法[10].該算法假設(shè)大多數(shù)大型軟件項目的目錄結(jié)構(gòu)是規(guī)范的和組織良好的,文件路徑與其功能是密切相關(guān)的.算法利用候選評審者的歷史評審文件路徑和新提交代碼涉及到的文件路徑的相似性來推薦評審者.在其隨后的研究[11]中進(jìn)一步使用了更加復(fù)雜的路徑相似性算法,比較兩條路徑的最長公共前綴、子序列等其他信息,并且添加了新的開源項目(Libre Office)來檢驗其效果.
Jiang等人利用開發(fā)者與評審者之間的社會關(guān)系屬性來推薦代碼評審者[12].他們研究發(fā)現(xiàn)使用機器學(xué)習(xí)中的Support Vector Machines方法可以得到最好的推薦表現(xiàn).但是因為他們的算法使用的實驗數(shù)據(jù)無法從其他軟件項目的公開數(shù)據(jù)中獲取,所以他們的研究結(jié)果沒有重復(fù)性和可比性.
上述評審者推薦方法大都沒有考慮到評審數(shù)據(jù)的時間效力和細(xì)粒度的評審內(nèi)容.評審的時間性能夠反映出評審者當(dāng)前的評審重心,所以越是近期的評審越重要,在進(jìn)行推薦時需要為當(dāng)前的評審賦予更高的時間效力,讓其發(fā)揮更大的作用.Thongtanunam等人使用了文件路徑來區(qū)分源代碼的功能,從而計算相似性,但這是一種粗粒度方法,無法詳盡的反映評審者的具體評審內(nèi)容,所以需要一種更細(xì)粒度化的標(biāo)準(zhǔn)來判別評審者的具體工作內(nèi)容,這樣就能夠得到更準(zhǔn)確的內(nèi)容相似性.
針對以上問題,本文提出了效力優(yōu)化的代碼評審者推薦模型OCRRM(optimized code reviewer recommendation model).OCRRM模型首先根據(jù)評審的發(fā)生時間調(diào)整本次評審的時間效力,為最近的評審賦予更高的時間效力,然后將候選評審者的歷史評審信息提取為細(xì)粒度的更具體的能夠詳細(xì)反映評審者具體評審內(nèi)容的信息,將提交代碼信息和候選評審者的歷史評審詳細(xì)信息的相似性作為內(nèi)容效力,最后利用候選評審者的每次歷史評審的時間效力作為內(nèi)容效力的權(quán)重來綜合推薦合適的代碼評審者.效力優(yōu)化主要是利用時間效力調(diào)整內(nèi)容效力的權(quán)重,既能夠利用詳細(xì)的具體的評審內(nèi)容,又能夠讓近期的歷史評審發(fā)揮更大的作用,所以可以能夠有效推薦合適的代碼評審者.
評審者的歷史評審數(shù)據(jù)主要分為兩部分:評審者R的個人信息、評審者R的歷史評審信息集合.R的歷史評審數(shù)據(jù)可以表示為HRD(R)=
R.Reviews = {
其中Owneri、Datei、RCodei和Commentsi分別表示R的第i次歷史評審的代碼提交者、提交時間、評審的代碼信息和評審流程中的所有評論.RCodei是通過分析修改的源代碼得到的文件名、方法名的信息集合,可以表示為:
RCodei=
不同時期的歷史評審活動對評審者的時間貢獻(xiàn)效力是不同的,近期的評審數(shù)據(jù)更能夠反映出評審者近期的評審重點.而且即使是同一個源代碼文件,不同的評審者的評審內(nèi)容和評審貢獻(xiàn)也是不同的.因而本文利用歷史評審數(shù)據(jù)的時間效力和內(nèi)容效力對代碼評審者推薦模型進(jìn)行優(yōu)化,利用時間效力和內(nèi)容效力來聯(lián)合推薦合適的代碼評審者.圖1給出了OCRRM的活動處理流程.
圖1中的OCRRM模型主要包含六個步驟:
1)獲取歷史評審信息
為了內(nèi)容效力的計算,需要首先獲取所有的歷史評審信息.利用網(wǎng)絡(luò)爬蟲從數(shù)據(jù)來源網(wǎng)站上獲取歷史評審的源數(shù)據(jù),然后將源數(shù)據(jù)分析整理為統(tǒng)一的HRD(R)格式,得到格式化的歷史評審數(shù)據(jù)集合,即HRD集合;
圖1 OCRRM模型流程圖
2)信息提取
利用文本提取從系統(tǒng)提交日志中提取出提交代碼的提交者信息,然后使用AST技術(shù)對源代碼中被修改的部分進(jìn)一步分析,提取被修改代碼涉及到的類、方法等詳細(xì)內(nèi)容;
3)獲取候選評審者集合
如果某個文件被某個評審者評審過,那么當(dāng)它被再次修改時,就應(yīng)該尋找曾經(jīng)評審過該文件的評審者作為候選評審者.如果新提交代碼涉及到的文件都沒有評審歷史,那么全體評審者都是其候選評審者.如果涉及到的文件擁有評審歷史,那么就應(yīng)該在HRD集合中尋找曾經(jīng)評審過該文件的評審者,并將該評審者加入候選評審者集合;
4)內(nèi)容效力計算
內(nèi)容效力CE度量候選評審者歷史評審內(nèi)容和新提交代碼內(nèi)容的相似度,內(nèi)容越相似,內(nèi)容效力越大.候選評審者的每次歷史評審數(shù)據(jù)都會涉及到不同的源代碼修改,使用AST技術(shù)將每次源代碼中修改部分提取為更具體的內(nèi)容,例如文件名、類名、方法名信息,可以反映出評審者的主要審核內(nèi)容.然后利用改進(jìn)的Jaccard相似度計算候選評審者的歷史評審內(nèi)容和提交代碼內(nèi)容的相似度,即內(nèi)容效力得分;
5)時間效力計算
時間效力TE度量候選評審者某次歷史評審發(fā)生時間和與當(dāng)前時間的時間間隔,間隔越小,時間效力越大.若候選評審者R的某次評審發(fā)生于t天之前,則這次評審的時間效力為1/(t+1),t>=0;
6)綜合推薦評審者
取得每個候選評審者的每次歷史評審的時間效力和內(nèi)容效力后,就可以綜合兩部分來推薦合適的評審者.為了防止越推薦越集中,越集中越推薦的情況,本文認(rèn)為只有內(nèi)容效力不為0的歷史評審才是具有效力的歷史評審,候選評審者的推薦得分是由所有具有效力的歷史評審的時間效力和內(nèi)容效力的乘積的和累加后除以有效評審次數(shù)得到的平均值,計算方法如公式(1)、公式(2)所示:
(1)
(2)
公式(1)、公式(2)中n表示候選的評審者R總的歷史評審次數(shù),CEi表示第i次歷史評審的內(nèi)容效力,TEi表示第i次歷史評審的時間效力,C表示在n次歷史評審中具有效力的評審次數(shù),即CEi大于0的評審次數(shù).這樣求得的推薦平均值就能夠剔除那些完全和新提交代碼無關(guān)的評審的影響,也能夠削弱評審者因為差異巨大的評審次數(shù)造成的影響.
計算出每個候選評審者的推薦得分后,根據(jù)推薦得分對候選評審者排序,然后就可以推薦前K名評審者.
在OCRRM模型中關(guān)鍵的技術(shù)主要有獲取歷史評審信息、候選評審者集合的獲取、歷史評審的時間效力和內(nèi)容效力的計算.
本文選取了三個網(wǎng)站的評審數(shù)據(jù)進(jìn)行分析,它們分別為QT、Android和Open Stack.這三個網(wǎng)站都可以獲取JSON格式的評審數(shù)據(jù),并且數(shù)據(jù)格式是相似的,這為數(shù)據(jù)的獲取提供了極大的便利.以QT項目為例,一次完整的評審數(shù)據(jù)主要包括評審代碼的提交信息、評審者、版本數(shù)、不同版本涉及到的源代碼和評審者對不同版本代碼的評論.利用網(wǎng)絡(luò)爬蟲從來源網(wǎng)站上獲取存在于detailjson、detailServicejson和patchesjson中的源數(shù)據(jù),通過解析json數(shù)據(jù),從detailjson中獲取評審涉及到的提交者、評審者、提交日志信息,從detailServicejson中獲取所有的提交源文件、版本數(shù)、評審評論等信息,從patchesjson中獲取某一版本涉及到的修改源文件、提交信息,最后將解析結(jié)果存入本地數(shù)據(jù)庫.獲取所有的解析數(shù)據(jù)后,將其再次處理格式化為HRD格式的數(shù)據(jù)存入數(shù)據(jù)庫.這樣所有的數(shù)據(jù)就獲取處理完成,需要的時候只要訪問本地數(shù)據(jù)庫即可.
為了推薦合適的代碼評審者,需要首先獲取候選的代碼評審者.如果一名提交者的提交代碼中的某個文件被某名評審者多次評審,那么當(dāng)提交者再次提交該段代碼時,就應(yīng)該找該名評審者來評審.
為了快速獲取候選的評審者集合,算法使用提交代碼信息NFiles、所有的歷史評審數(shù)據(jù)HRD集合作為輸入,輸出候選評審者集合Revs.NFiles包含新提交代碼中涉及到的所有文件名.程序遍歷HRD集合,從中取出每一條HRD(R)數(shù)據(jù),然后遍歷HRD(R)數(shù)據(jù)中的R.Review集合.如果NFiles中的文件被R.Review評審過,即評審者某次評審的文件中包含新提交代碼中的任一文件,那么就將該條HRD(R)所屬的R.Profile加入輸出的評審者集合Revs.
獲取候選評審者偽算法如下:
輸入:代碼的提交者信息 NFiles=
候選評審者的歷史評審數(shù)據(jù)包含了評審者開始評審該項目到至今的所有評審數(shù)據(jù),時間跨度可能很長.如果將所有時間跨度的評審數(shù)據(jù)的時間效力看作一樣的,則會出現(xiàn)讓一個長久沒有評審的評審者評審新提交代碼的情況.為了把代碼推薦給能夠及時反應(yīng)的評審人員,需要使用效力優(yōu)化函數(shù)對不同時間跨度的歷史評審數(shù)據(jù)的時間效力進(jìn)行調(diào)整.對于某位候選評審者R,第i次歷史評審的時間效力計算如公式(3)如示:
(3)
公式(3)中DN(以天為時間度量單位)表示當(dāng)前時間,DRCi代表R第i次歷史評審的發(fā)生時間.評審者R的歷史評審發(fā)生時間距當(dāng)前時間越近,則t越小,時間效力越大,最大為1,最小趨近于0.為了防止除0,在分母上加1.
某段代碼可能會被修改和提交評審過多次,產(chǎn)生多個版本.本文將每次代碼的修改提交都看作一次評審,即對于每一版本的代碼修改都看作是一次評審,這樣就可以充分利用足夠細(xì)化的數(shù)據(jù).但是通過對評審的評論分析發(fā)現(xiàn),在評審的版本演進(jìn)過程中,并不是所有的評審者都在評審過程中留下了評論,這就造成了某些評審者的評審意見為空.可是他們作為評審流程的一員,應(yīng)該是做出了部分貢獻(xiàn),理應(yīng)擁有評審數(shù)據(jù),所以本文將版本演進(jìn)造成的多次評審中的第一版評審數(shù)據(jù)作為所有評審者的基本數(shù)據(jù).以QT項目的153840號Project評審*https://codereview.qt-project.org/#/c/153840/為例,該Project共有四個版本,看作四次評審,Patch Set 1中修改的類和方法作為該次評審所有評審者的基本數(shù)據(jù).通過評論發(fā)現(xiàn),Patch Set 2的評審數(shù)據(jù)應(yīng)該是Leena的,而Patch Set 3和Patch Set 4號的評審數(shù)據(jù)分別是屬于Marc和Olivier的.
在得到評審者的歷史評審內(nèi)容和新提交代碼內(nèi)容后,使用改進(jìn)的Jaccard相似度計算方法可以計算出評審者每一次的評審代碼內(nèi)容和新提交代碼內(nèi)容的相似度,即每一次的評審內(nèi)容效力.
Jaccard相似度[13]是用來度量兩個不同維數(shù)集合之間的相似程度,又稱之為狹義Jaccard相似度,兩個集合的狹義相似度等于兩個集合的交集比上兩個集合的并集.但是本文在以新提交代碼內(nèi)容為基礎(chǔ)度量新提交代碼內(nèi)容和歷史評審內(nèi)容的相似度時,更應(yīng)該著重注意歷史評審內(nèi)容對新提交代碼內(nèi)容的覆蓋程度,即提交代碼內(nèi)容和歷史評審內(nèi)容的共有元素個數(shù)越多,對新提交代碼內(nèi)容的覆蓋程度越大,相似度越大.為此,本文提出了改進(jìn)的Jaccard相似度,利用改進(jìn)Jaccard相似度計算新提交代碼內(nèi)容和歷史評審內(nèi)容的相似性.設(shè)新提交代碼的類集合P共有i個元素,歷史評審數(shù)據(jù)的類集合R共有j個元素,則P和R的交集G共有k個元素,如公式(4)-公式(6)所示:
P={p0,p1,…,pi}
(4)
R={r0,r1,…,rj}
(5)
G=P∩R={g0,g1,…,gk}, 0≤k
≤Min(i,j)
(6)
以P和R為基礎(chǔ)計算改進(jìn)Jaccard相似度,如公式(7)所示:
(7)
公式(7)中|P|表示集合P的模,即P中元素的個數(shù),|P∩R|表示集合P與R交集的模.k/i越大,表示評審內(nèi)容和新提交代碼內(nèi)容的共有元素個數(shù)越大,即候選評審者評審內(nèi)容和新提交代碼內(nèi)容越相近.
通過AST技術(shù)對評審者的歷史評審源代碼進(jìn)行分析,提取其中被修改的類名和方法名.若評審者R的第i次歷史評審的類名相似度為CJ,方法名相似度為MJ,則R的第i次歷史評審內(nèi)容的內(nèi)容效力CE計算方法如公式(8)如表示:
CE(R,i)=a*CJ+(1-a)*MJ
(8)
公式(8)中a表示類名相似度的權(quán)重,1-a表示方法名相似度的權(quán)重.
本文采用的數(shù)據(jù)來自三個網(wǎng)上公開的代碼評審項目,它們分別是QT*https://codereview.qt-project.org/、Android(AN)*https://android-review.googlesource.com和Open Stack(OP)*https://review.openstack.org/#/q/status:merged.每個項目開發(fā)時間均超過五年,評審流程已經(jīng)非常地成熟穩(wěn)定.三個項目的大部分評審數(shù)據(jù)都是公開的,均可以在網(wǎng)上獲取.從三個項目網(wǎng)站中分別獲取id連續(xù)的3萬條數(shù)據(jù),QT項目中id取150000-180000、AN項目中id取350000-380000、OP項目中id取350000-380000萬.這些數(shù)據(jù)都是近期的,可以保證數(shù)據(jù)是有效的和穩(wěn)定的.從預(yù)處理的數(shù)據(jù)中選取公開的并且已合并的數(shù)據(jù)進(jìn)行統(tǒng)計,統(tǒng)計結(jié)果如表1所示:
從表2中可以看出,OP項目的開源評審次數(shù)是最多的,數(shù)據(jù)也是最豐富的,QT項目的評審次數(shù)和數(shù)據(jù)豐富程度次之,AN項目的最少.以QT項目為例,選取的數(shù)據(jù)時間從2016/02/22到2016/12/15,共有19504次公開的已合并的項目評審,在19504次項目評審中,共涉及到681位評審者和54687個文件,681位評審者共評審了代碼修改51119次,評審了文件116664次,評審了72555次不同版本的代碼修改.平均每次項目合并涉及到2.62次評審、5.98個文件和3.72個版本.
表1 實驗數(shù)據(jù)統(tǒng)計
本文主要通過Top-k準(zhǔn)確率和推薦平均準(zhǔn)確率來對實驗結(jié)果進(jìn)行分析.對于公式(8)中的內(nèi)容效力CE中a的取值,本文經(jīng)過一部分實驗選取其最優(yōu)取值為0.76.
表2 TOP-K準(zhǔn)確率對比
Top-k準(zhǔn)確率表示算法推薦的前k名評審者的準(zhǔn)確率.K越小,Top-k越高,表示推薦算法的推薦效果越好.當(dāng)Top-1準(zhǔn)確率為1時,表示算法總能推薦想要的結(jié)果,這是最理想的情況.給定一個推薦的評審者集合Rc和實際的評審者結(jié)合Rr,如公式(9)、公式(10),則Top-k準(zhǔn)確率計算方法如公式(11)如示:
RC={r0,r1…ri},i=0,1,…k
(9)
Rr={r0,r1…ri},j=0,1,…n
(10)
(11)
如果實際評審者Rr中的前k名評審者包含推薦的第i名評審者ri,則isContain()函數(shù)返回1,否則返回0.根據(jù)文獻(xiàn)[12],本文中選擇k值為1、3、5.例如,Rr={a,b,c,d,e},Rc={a,c,f,b,e,d},則Top-1、Top-3、Top-5準(zhǔn)確率依次為100%、66.7%和80%.
OP、QT和AN項目的Top-k準(zhǔn)確率如表2所示.表2中共包含了四種方法OCRRM、REVIEWBOT、Number of Changes和Expertise Recommender(ER)在三個項目上的TOP-K值[11].本文模型OCCRM在三個項目上的Top-5準(zhǔn)確率達(dá)到了63%、54%和58%,而ER的TOP-5準(zhǔn)確率只有51%、53%和54%.從表中可以看出,在QT項目上的TOP-K準(zhǔn)確率兩者大致是相同的,而OP項目上的TOP-K準(zhǔn)確率OCCRM模型更高.雖然在AN項目上的TOP-1和TOP-3是ER方法更好,但是TOP-5準(zhǔn)確率仍是OCCRM方法更好,說明OCCRM模型能夠有效地提高推薦準(zhǔn)確率,尤其是推薦人數(shù)較多的時候.
推薦平均準(zhǔn)確率表示推薦的專家中實際參加了評審的專家的比例.在統(tǒng)計三個實驗項目的推薦平均準(zhǔn)確率時,每進(jìn)行10次評審者推薦統(tǒng)計一次推薦平均準(zhǔn)確率.三個項目的推薦平均準(zhǔn)確率如圖2所示.
圖2 OP、QT和AN的推薦平均準(zhǔn)確率
從圖2中可以看出,三個項目的推薦平均準(zhǔn)確率在訓(xùn)練的初期因為數(shù)據(jù)的缺乏都很低.隨著數(shù)據(jù)的豐富,推薦平均準(zhǔn)確率迅速上升,達(dá)到收斂后在收斂準(zhǔn)確率附近變化.OP項目的訓(xùn)練使用了約15%的評審數(shù)據(jù),推薦平均準(zhǔn)確率收斂后可以達(dá)到74.42%.QT項目的訓(xùn)練使用了約22%的評審數(shù)據(jù),推薦平均準(zhǔn)確率收斂后為64.63%.AN項目的訓(xùn)練使用了約34%的評審數(shù)據(jù),推薦平均準(zhǔn)確率收斂后為67.27%.而在文獻(xiàn)[11]中,Expertise Cloud方法在三個項目上的平均準(zhǔn)確率約為65.3%、60.3%和59.6%,Expertise Recommender方法的平均準(zhǔn)確率約為58.8%、55.9%和58.5%.由此可見本文的OCCRM模型可以達(dá)到較高的推薦平均準(zhǔn)確率,證明本文的方法有效.
基于評審歷史的代碼評審者推薦方法是代碼評審的主要研究方向之一.本文提出的效力優(yōu)化的代碼評審者推薦模型OCRRM考慮了不同時期發(fā)生的歷史評審數(shù)據(jù)對最終的推薦結(jié)果的影響,并且將歷史評審數(shù)據(jù)提取為能夠反映評審者評審具體內(nèi)容和貢獻(xiàn)的內(nèi)容.在三個大型開源軟件公開評審數(shù)據(jù)上的實驗證明本模型能夠有效的提高代碼評審者的推薦準(zhǔn)確率.雖然本文的實驗數(shù)據(jù)很豐富,但是選取的數(shù)據(jù)都是三個項目中的連續(xù)的一部分,沒有從頭到尾的對一個項目完整的進(jìn)行實驗,以驗證本模型在完整項目實驗數(shù)據(jù)上的有效性.因此在后續(xù)工作中將進(jìn)一步優(yōu)化程序和驗證完整的項目數(shù)據(jù).