本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,尤其涉及一種覆蓋率數(shù)據(jù)的處理方法、裝置和服務(wù)器。
背景技術(shù):
代碼覆蓋率測試,是軟件測試過程中最重要的測試方法和測試效果衡量標(biāo)準(zhǔn)之一,覆蓋率指的是源代碼執(zhí)行過程中被測試所覆蓋到代碼的比例和程度,通常用百分比表示。
對(duì)不同的編程語言來說,都有相應(yīng)的檢測代碼覆蓋率的方法。在針對(duì)游戲服務(wù)器的python代碼覆蓋率檢測的過程中,通常使用的技術(shù)方案是利用python自帶的sys.settrace函數(shù)進(jìn)行數(shù)據(jù)收集和處理,在停止采集之后,一次性地導(dǎo)出覆蓋率數(shù)據(jù)報(bào)告。由于代碼覆蓋率檢測的實(shí)時(shí)性要求,隨著游戲規(guī)模的增大和項(xiàng)目的發(fā)展,需要測試的代碼量越來越高,如何更好地維護(hù)和存儲(chǔ)覆蓋率測試中獲取的覆蓋率數(shù)據(jù)成為了必須解決的問題。一般來說,覆蓋率數(shù)據(jù),包括了文件覆蓋率數(shù)據(jù)和目錄覆蓋率數(shù)據(jù),每個(gè)文件的已執(zhí)行過的代碼行號(hào)集合,該文件總的可執(zhí)行代碼行號(hào)集合等等,而每當(dāng)有新的覆蓋率數(shù)據(jù)到來,比如某個(gè)文件的一些代碼被執(zhí)行,那么就需要重新計(jì)算當(dāng)前文件、當(dāng)前文件所在的目錄甚至于總體的覆蓋率數(shù)據(jù)。目前一種具體的獲取覆蓋率數(shù)據(jù)的方式是利用python的sys模塊中提供settrace函數(shù),跟蹤代碼的執(zhí)行情況,將覆蓋率數(shù)據(jù)存儲(chǔ)到Collector中的Stack中。每當(dāng)開始采集時(shí),Collector不斷執(zhí)行入棧操作,停止采集時(shí),通過出棧操作即可獲取已采集的覆蓋率數(shù)據(jù)。
然而,當(dāng)需要測試的代碼量較大時(shí),每當(dāng)有新數(shù)據(jù)到來,需要存儲(chǔ)和重新計(jì)算覆蓋率,給內(nèi)存和計(jì)算性能帶來了很大負(fù)擔(dān),甚至?xí)绊懙奖粶y試程序的運(yùn)行,一定程度上降低了測試的效率和質(zhì)量。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明實(shí)施例提供一種覆蓋率數(shù)據(jù)的處理方法、裝置和服務(wù)器,用于解決目前的方案中,當(dāng)需要測試的代碼量較大時(shí),每當(dāng)有新數(shù)據(jù)到來,需要存儲(chǔ)和重新計(jì)算覆蓋率,給內(nèi)存和計(jì)算性能帶來了很大負(fù)擔(dān),甚至?xí)绊懙奖粶y試程序的運(yùn)行,一定程度上降低了測試的效率和質(zhì)量的問題。
本發(fā)明第一方面提供一種覆蓋率數(shù)據(jù)的處理方法,包括:
接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù);
查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn);
根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
可選的,所述獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn)之后,所述方法還包括:
將所述第一子節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)更新為所述覆蓋率數(shù)據(jù)。
可選的,所述接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù)之前,所述方法包括:
根據(jù)每個(gè)文件的文件名稱和目錄信息建立所述樹形存儲(chǔ)結(jié)構(gòu);其中,所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)下包括至少一層以目錄信息以及文件名稱逐層建立的子節(jié)點(diǎn);
根據(jù)每個(gè)子節(jié)點(diǎn)下的文件的執(zhí)行數(shù)據(jù)計(jì)算獲取與所述子節(jié)點(diǎn)對(duì)應(yīng)的覆蓋率。
可選的,所述根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率,包括:
通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù);
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),以及每個(gè)與所述第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),計(jì)算獲取所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),將所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)作為第一子節(jié)點(diǎn),重復(fù)本步驟直至計(jì)算出所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)的處的總代碼行數(shù)和已執(zhí)行代碼行數(shù);
根據(jù)所述根節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),計(jì)算獲取所述服務(wù)器的所述總體覆蓋率。
可選的,通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)之后,還包括:
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)計(jì)算所述第一子節(jié)點(diǎn)的覆蓋率;
將所述第一子節(jié)點(diǎn)的覆蓋率進(jìn)行更新并予以顯示。
本發(fā)明第二方面提供一種覆蓋率檢測裝置,包括:
接收模塊,用于接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù);
處理模塊,用于查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn);
所述處理模塊還用于根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
可選的,所述裝置還包括:
存儲(chǔ)模塊,用于將所述第一子節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)更新為所述覆蓋率數(shù)據(jù)。
可選的,所述接收模塊接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù)之前,所述處理模塊還用于:
根據(jù)每個(gè)文件的文件名稱和目錄信息建立所述樹形存儲(chǔ)結(jié)構(gòu);其中,所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)下包括至少一層以目錄信息以及文件名稱逐層建立的子節(jié)點(diǎn);
根據(jù)每個(gè)子節(jié)點(diǎn)下的文件的執(zhí)行數(shù)據(jù)計(jì)算獲取與所述子節(jié)點(diǎn)對(duì)應(yīng)的覆蓋率。
可選的,所述處理模塊具體用于:
通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù);
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),以及每個(gè)與所述第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),計(jì)算獲取所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),將所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)作為第一子節(jié)點(diǎn),重復(fù)本步驟直至計(jì)算出所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)的處的總代碼行數(shù)和已執(zhí)行代碼行數(shù);
根據(jù)所述根節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),計(jì)算獲取所述服務(wù)器的所述總體覆蓋率。
可選的,所述處理模塊還用于:
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)計(jì)算所述第一子節(jié)點(diǎn)的覆蓋率;
控制將所述第一子節(jié)點(diǎn)的覆蓋率進(jìn)行更新并予以顯示。
本發(fā)明第三方面提供一種服務(wù)器,包括:存儲(chǔ)有程序指令的存儲(chǔ)器、接收器和用于控制程序指令執(zhí)行的處理器;
所述接收器用于接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù);
所述處理器用于:
查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn);
根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法、裝置和服務(wù)器,在覆蓋率服務(wù)器側(cè)對(duì)接收到的每個(gè)服務(wù)器的數(shù)據(jù)建立樹形存儲(chǔ)結(jié)構(gòu),在接收到服務(wù)器發(fā)送的包括文件名稱和對(duì)應(yīng)的覆蓋率數(shù)據(jù)時(shí)候,按照文件名稱逐個(gè)節(jié)點(diǎn)查詢只對(duì)該節(jié)點(diǎn)的覆蓋率數(shù)據(jù)進(jìn)行修改,只需要對(duì)覆蓋率數(shù)據(jù)改變了的節(jié)點(diǎn)重新計(jì)算,然后結(jié)合其他的節(jié)點(diǎn)上的已知的數(shù)據(jù)計(jì)算出該服務(wù)器的總體覆蓋率,不需要對(duì)所有文件遍歷統(tǒng)計(jì),有效減小全局?jǐn)?shù)據(jù)修改和覆蓋率計(jì)算帶來的性能消耗,提高測試效率。
附圖說明
為了更清楚地說明本發(fā)明實(shí)施例或現(xiàn)有技術(shù)中的技術(shù)方案,下面將對(duì)實(shí)施例或現(xiàn)有技術(shù)描述中所需要使用的附圖作一簡單地介紹,顯而易見地,下面描述中的附圖是本發(fā)明的一些實(shí)施例,對(duì)于本領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動(dòng)性的前提下,還可以根據(jù)這些附圖獲得其它的附圖。
圖1為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法實(shí)例一的流程圖;
圖2為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法實(shí)例二的流程圖;
圖3為本發(fā)明實(shí)施例提供的樹形存儲(chǔ)結(jié)構(gòu)的實(shí)例示意圖;
圖4為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法在覆蓋率服務(wù)器側(cè)的實(shí)例的流程圖;
圖5為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置實(shí)施例一的結(jié)構(gòu)示意圖;
圖6為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置實(shí)施例二的結(jié)構(gòu)示意圖;
圖7為本發(fā)明實(shí)施例提供的服務(wù)器實(shí)施例一的結(jié)構(gòu)示意圖。
具體實(shí)施方式
為使本發(fā)明實(shí)施例的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合本發(fā)明實(shí)施例中的附圖,對(duì)本發(fā)明實(shí)施例中的技術(shù)方案進(jìn)行清楚、完整地描述,顯然,所描述的實(shí)施例是本發(fā)明一部分實(shí)施例,而不是全部的實(shí)施例?;诒景l(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有作出創(chuàng)造性勞動(dòng)前提下所獲得的所有其它實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。
圖1為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法實(shí)例一的流程圖,如圖1所示,該方案的執(zhí)行主體為用于檢測覆蓋率的服務(wù)器(即覆蓋率服務(wù)器),或者檢測覆蓋率的其他設(shè)備,該覆蓋率檢測方法的具體實(shí)現(xiàn)步驟為:
步驟S101,接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù)。
在本實(shí)施例中,這里發(fā)送執(zhí)行數(shù)據(jù)的服務(wù)器為執(zhí)行該文件的程序的服務(wù)器,例如:運(yùn)行游戲程序的服務(wù)器。該方案中的執(zhí)行文件代碼的服務(wù)器需要獲取被執(zhí)行的文件的文件名稱以及覆蓋率數(shù)據(jù),該覆蓋率數(shù)據(jù)至少包括能夠指示被執(zhí)行的文件已經(jīng)執(zhí)行的行數(shù)的信息,例如:當(dāng)前執(zhí)行的行號(hào),或者已經(jīng)執(zhí)行的行數(shù)等。
步驟S102,查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn)。
該方案中,覆蓋率服務(wù)器端將接收到的上述服務(wù)器發(fā)送來的所有文件的執(zhí)行數(shù)據(jù)按照樹形存儲(chǔ)結(jié)構(gòu)進(jìn)行存儲(chǔ),每個(gè)節(jié)點(diǎn)可以使用文件的名稱進(jìn)行命名,節(jié)點(diǎn)下存儲(chǔ)該文件名稱對(duì)應(yīng)的文件的覆蓋率數(shù)據(jù)。
在后續(xù)接收到該服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù)之后,根據(jù)其中的文件名稱逐層節(jié)點(diǎn)進(jìn)行查詢,將查詢到的與該文件名稱對(duì)應(yīng)第一子節(jié)點(diǎn)。
可選的,可將該第一子節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)更新為執(zhí)行數(shù)據(jù)中的覆蓋率數(shù)據(jù)。
步驟S103,根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
本方案中,要獲取到上述服務(wù)器的總體覆蓋率,不需要對(duì)該服務(wù)器的所有文件解析一遍,只需要對(duì)接收到的執(zhí)行數(shù)據(jù)中的文件名稱對(duì)應(yīng)的覆蓋率數(shù)據(jù)以及該文件的源代碼文件進(jìn)行解析處理,然后結(jié)合與第一子節(jié)點(diǎn)同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),得到這一層的已經(jīng)執(zhí)行的代碼行數(shù)以及所有文件的源代碼行數(shù)的總和,然后根據(jù)該方式逐層累加,得到該服務(wù)器上總體的已執(zhí)行代碼行數(shù)以及所有源代碼總行,然后根據(jù)覆蓋率公式計(jì)算可得到該服務(wù)器的總體覆蓋率。
本實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法,在覆蓋率服務(wù)器側(cè)對(duì)接收到的每個(gè)服務(wù)器的數(shù)據(jù)建立樹形存儲(chǔ)結(jié)構(gòu),在接收到服務(wù)器發(fā)送的包括文件名稱和對(duì)應(yīng)的覆蓋率數(shù)據(jù)時(shí)候,按照文件名稱逐個(gè)節(jié)點(diǎn)查詢只對(duì)該節(jié)點(diǎn)的覆蓋率數(shù)據(jù)進(jìn)行修改,只需要對(duì)覆蓋率數(shù)據(jù)改變了的節(jié)點(diǎn)重新計(jì)算,然后結(jié)合其他的節(jié)點(diǎn)上的已知的數(shù)據(jù)計(jì)算出該服務(wù)器的總體覆蓋率,不需要對(duì)所有文件遍歷統(tǒng)計(jì),有效減小全局?jǐn)?shù)據(jù)修改和覆蓋率計(jì)算帶來的性能消耗,提高測試效率。
圖2為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法實(shí)例二的流程圖,如圖2所示,在上述實(shí)施例的基礎(chǔ)上,在根據(jù)文件名稱查詢樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn)之前,該覆蓋率數(shù)據(jù)的處理方法還包括:
步驟S201,根據(jù)每個(gè)文件的文件名稱和目錄信息建立所述樹形存儲(chǔ)結(jié)構(gòu);其中,所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)下包括至少一層以目錄信息以及文件名稱逐層建立的子節(jié)點(diǎn)。
步驟S202,根據(jù)每個(gè)子節(jié)點(diǎn)下的文件的執(zhí)行數(shù)據(jù)計(jì)算獲取與所述子節(jié)點(diǎn)對(duì)應(yīng)的覆蓋率。
在方案中,在覆蓋率服務(wù)器端,對(duì)于每個(gè)服務(wù)器的文件數(shù)據(jù)等需要預(yù)先建立樹形存儲(chǔ)結(jié)構(gòu),具體的建立的方式是:根(Root)節(jié)點(diǎn)表示根目錄,根節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)包括:總代碼行數(shù)(由所有子節(jié)點(diǎn)的文件的代碼行數(shù)相加得來),總已執(zhí)行代碼行數(shù)(由所有子節(jié)點(diǎn)的覆蓋率數(shù)據(jù)獲取到的已執(zhí)行行數(shù)相加得來),以及總的覆蓋率數(shù)據(jù)(由總的已執(zhí)行代碼行數(shù)除以總代碼行數(shù)得到)。
在根節(jié)點(diǎn)下包括一層或者多層的子節(jié)點(diǎn),其他子節(jié)點(diǎn)主要分為兩類,一類是文件節(jié)點(diǎn),代表某個(gè)文件(例如:Python的py文件)的覆蓋率數(shù)據(jù),包括該文件已經(jīng)執(zhí)行過的代碼行數(shù),和該文件源碼中的可執(zhí)行代碼總行數(shù),以及該文件的覆蓋率數(shù)值。
另一類是目錄節(jié)點(diǎn),包含的是該目錄下,所有文件和目錄覆蓋率數(shù)據(jù)的對(duì)應(yīng)項(xiàng)之和,即該目錄下所有文件和目錄的總的已執(zhí)行代碼行數(shù),和總的可執(zhí)行代碼行數(shù),以及由這兩項(xiàng)數(shù)據(jù)計(jì)算出來的覆蓋率數(shù)值。
每當(dāng)有數(shù)據(jù)到達(dá)時(shí),根據(jù)目錄結(jié)構(gòu)依次添加和修改對(duì)應(yīng)節(jié)點(diǎn),如果某個(gè)文件的覆蓋率數(shù)據(jù)發(fā)送變化,則可以根據(jù)文件名稱逐層查詢所有的節(jié)點(diǎn),將該文件的覆蓋率數(shù)據(jù)更新為變化后的覆蓋率數(shù)據(jù),然后重新計(jì)算出該文件的覆蓋率。
這種存儲(chǔ)方式下,無論是對(duì)某個(gè)文件的覆蓋率數(shù)據(jù)進(jìn)行修改更新,還是獲取某個(gè)文件的覆蓋率,還是獲取總體的覆蓋率,均不需要再去遍歷所有的文件的數(shù)據(jù)去重新計(jì)算,只需要對(duì)變化了的節(jié)點(diǎn)進(jìn)行重新計(jì)算即可,解決了代碼量比較大時(shí),全局?jǐn)?shù)據(jù)修改和覆蓋率數(shù)據(jù)重新計(jì)算時(shí)計(jì)算量較大的問題,降低性能消耗。
在上述兩個(gè)實(shí)施例的基礎(chǔ)上,下面以一種具體的實(shí)現(xiàn)方式對(duì)本發(fā)明提供的覆蓋率數(shù)據(jù)的處理方法進(jìn)行說明。
同樣的,該方案在具體實(shí)現(xiàn)中涉及運(yùn)行文件代碼的服務(wù)器端(以游戲服務(wù)器為例)以及覆蓋率服務(wù)器端,具體包括數(shù)據(jù)采集、數(shù)據(jù)存儲(chǔ)以及覆蓋率數(shù)據(jù)重新計(jì)算三部分。
1、初始化過程
初始化過程分為啟動(dòng)覆蓋率數(shù)據(jù)處理服務(wù)器和嵌入覆蓋率采集客戶端到游戲服務(wù)器腳本中兩個(gè)部分。
覆蓋率服務(wù)器側(cè)的架構(gòu)基于Tornado構(gòu)建,主要功能是通過websocket接收來自通過一定規(guī)則(見下文中的進(jìn)程標(biāo)識(shí)步驟)標(biāo)識(shí)的客戶端的數(shù)據(jù),并定時(shí)將同一游戲服務(wù)器的數(shù)據(jù)合并和處理。在游戲服務(wù)器啟動(dòng)測試之前,首先啟動(dòng)覆蓋率服務(wù)器,等待客戶端連接和收集數(shù)據(jù)。
對(duì)于客戶端,在游戲服務(wù)器中啟動(dòng)不同進(jìn)程的腳本中,添加使用線程啟動(dòng)websocket連接的代碼,具體如下:
ws=websocket.WebSocket("ws://websocket_address/")
thread_ws=threading.Thread(target=ws.run)
thread_ws.start()
該線程用于在每個(gè)游戲服務(wù)器進(jìn)程啟動(dòng)websocket并連接到覆蓋率服務(wù)器后,進(jìn)行定時(shí)的數(shù)據(jù)發(fā)送。
2、數(shù)據(jù)采集過程,該過程在游戲服務(wù)器中實(shí)現(xiàn)
嵌入游戲服務(wù)器的客戶端,主要通過添加如下代碼實(shí)現(xiàn)數(shù)據(jù)采集:
即利用python自帶的sys.settrace方法,在游戲服務(wù)器腳本運(yùn)行過程中,每當(dāng)發(fā)生了代碼執(zhí)行事件(event),就會(huì)調(diào)用trace方法進(jìn)行跟蹤,其中frame表示python運(yùn)行過程中的棧幀,event表示發(fā)生的事件(例如執(zhí)行了某一行代碼,或者調(diào)用了某個(gè)函數(shù)等)。使用frame.f_code.co_filename獲取被執(zhí)行的文件名稱fliename,使用frame.f_lineno獲取當(dāng)前執(zhí)行的代碼行號(hào),然后調(diào)用collect方法進(jìn)行數(shù)據(jù)收集,該方法主要是使用了字典(python的一種內(nèi)置數(shù)據(jù)結(jié)構(gòu),以鍵-值對(duì)格式存儲(chǔ)數(shù)據(jù))的形式,將數(shù)據(jù)以文件名為鍵,以被執(zhí)行的代碼行號(hào)集合為值的形式存儲(chǔ),舉例如下:
其中root/directory1/.../file1表示被測試的代碼文件的路徑,set([lineno11,lineno12,lineno13...])表示一個(gè)集合,該集合中的元素有l(wèi)ineno11,lineno12,lineno13等等,每個(gè)元素表示file1中進(jìn)行覆蓋率測試時(shí),被執(zhí)行過的行號(hào)(lineno)。
游戲服務(wù)器在獲取到上述的數(shù)據(jù)之后需要發(fā)送給覆蓋率服務(wù)器,即覆蓋率服務(wù)器通過嵌入游戲服務(wù)器中的客戶端獲取到上述數(shù)據(jù),需要在本地進(jìn)行存儲(chǔ)和處理,具體的實(shí)現(xiàn)過程如下。
首先建立樹形存儲(chǔ)結(jié)構(gòu)對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ),圖3為本發(fā)明實(shí)施例提供的樹形存儲(chǔ)結(jié)構(gòu)的實(shí)例示意圖,如圖3所示,根節(jié)點(diǎn)表示根目錄,其中包含的數(shù)據(jù)有總代碼行數(shù)(由所有子節(jié)點(diǎn)的數(shù)據(jù)相加得來),總已執(zhí)行代碼行數(shù)(由所有子節(jié)點(diǎn)的數(shù)據(jù)相加得來),以及總的覆蓋率數(shù)據(jù)(由總的已執(zhí)行代碼行數(shù)除以總代碼行數(shù)得到)。
其他節(jié)點(diǎn)主要分為兩類,一類是文件節(jié)點(diǎn),代表某個(gè)文件(例如Python的py文件)的覆蓋率數(shù)據(jù),包括該文件已經(jīng)執(zhí)行過的代碼行數(shù),和該文件源碼中的可執(zhí)行代碼總行數(shù),以及該文件的覆蓋率數(shù)值。
另一類是目錄節(jié)點(diǎn),包含的是該目錄下,所有文件和目錄覆蓋率數(shù)據(jù)的對(duì)應(yīng)項(xiàng)之和,即該目錄下所有文件和目錄的總的已執(zhí)行代碼行數(shù),和總的可執(zhí)行代碼行數(shù),以及由這兩項(xiàng)數(shù)據(jù)計(jì)算出來的覆蓋率數(shù)值。
圖4為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理方法在覆蓋率服務(wù)器側(cè)的實(shí)例的流程圖;如圖4所示,在覆蓋率服務(wù)器側(cè),存儲(chǔ)和處理過程具體如下:
步驟S301,接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù)。
步驟S302,查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn)。
步驟S303,將所述第一子節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)更新為所述覆蓋率數(shù)據(jù)。
在上述幾個(gè)步驟的具體實(shí)現(xiàn)跟實(shí)施例一種類似。
具體的,如圖3所示的結(jié)構(gòu),每當(dāng)有執(zhí)行數(shù)據(jù)到達(dá)時(shí),根據(jù)目錄結(jié)構(gòu)依次添加和修改對(duì)應(yīng)節(jié)點(diǎn),即將執(zhí)行數(shù)據(jù)對(duì)應(yīng)的節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行更新,例如,某文件名稱為directory01/file11.py,則首先從根目錄開始搜索,找到directory01節(jié)點(diǎn),然后繼續(xù)向下搜索,找到file11節(jié)點(diǎn),覆蓋率數(shù)據(jù)的格式,已執(zhí)行的代碼行數(shù)由上節(jié)所述('root/directory1/.../file1':set([lineno11,lineno12,lineno13...]))表示。
如果需要獲取該服務(wù)器的總體覆蓋率,則在執(zhí)行完上述步驟后,可按照步驟S304-S306所示的步驟進(jìn)行執(zhí)行。
步驟S304,通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)。
步驟S305,根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),以及每個(gè)與所述第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),計(jì)算獲取所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),將所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)作為第一子節(jié)點(diǎn),重復(fù)本步驟直至計(jì)算出所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)的處的總代碼行數(shù)和已執(zhí)行代碼行數(shù)。
在本步驟之后,可選的,由于第一子節(jié)點(diǎn)處的覆蓋率數(shù)據(jù)發(fā)生變化,因此該第一子節(jié)點(diǎn)處的文件的覆蓋率也發(fā)生變化,在具體實(shí)現(xiàn)中可以根據(jù)得到的第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)重新計(jì)算該第一子節(jié)點(diǎn)處的覆蓋率,并將第一子節(jié)點(diǎn)處原來存儲(chǔ)的覆蓋率更新為重新計(jì)算得到的覆蓋率,并可以根據(jù)查詢請求予以顯示,或者直接展示給用戶。
步驟S306,根據(jù)所述根節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),計(jì)算獲取所述服務(wù)器的所述總體覆蓋率。
上述幾個(gè)步驟的含義是:每個(gè)文件子節(jié)點(diǎn)分別記錄覆蓋率數(shù)據(jù)的中的已執(zhí)行行數(shù)與源代碼行數(shù),在計(jì)算總覆蓋率時(shí),需要將跟節(jié)點(diǎn)(根目錄)進(jìn)行數(shù)據(jù)匯總,逐層將每個(gè)節(jié)點(diǎn)的已執(zhí)行行數(shù)相加,再將所有代源碼行數(shù)相加,然后使用根節(jié)點(diǎn)處的已執(zhí)行行數(shù)除以總代碼行數(shù)得到總覆蓋率。
對(duì)于各個(gè)子節(jié)點(diǎn)來說,雖然根節(jié)點(diǎn)并不直接使用各自的覆蓋率,但還是會(huì)分別計(jì)算自身的覆蓋率,并將得到的節(jié)點(diǎn)處的覆蓋率進(jìn)行存儲(chǔ),根據(jù)查詢請求進(jìn)行展示。
如圖3所示實(shí)例,可通過len(set([lineno11,lineno12,lineno13...]))計(jì)算行號(hào)集合的大小即可得到,而可執(zhí)行代碼行數(shù)則由源碼文件解析而來,具體步驟是根據(jù)數(shù)據(jù)中的文件名,找到對(duì)應(yīng)本地源碼文件進(jìn)行解析,解析的過程是去除空白行和注釋行,從而計(jì)算出真正的可執(zhí)行代碼行的總數(shù)。由上述步驟,獲得了每個(gè)文件當(dāng)前所執(zhí)行過的代碼行號(hào)的集合,已知覆蓋率計(jì)算公式為:
其中,Rate表示覆蓋率,lineexecute表示已經(jīng)執(zhí)行過的代碼行數(shù),linetotal可執(zhí)行代碼行總數(shù)。
根據(jù)所有文件中可執(zhí)行代碼的總行數(shù)以及已經(jīng)執(zhí)行的行數(shù),計(jì)算得到該服務(wù)器的總覆蓋率。
在上述方案中,每當(dāng)新數(shù)據(jù)到來,依次修改到文件子節(jié)點(diǎn)后,首先對(duì)子節(jié)點(diǎn)發(fā)生變化的父節(jié)點(diǎn)(目錄節(jié)點(diǎn))重新計(jì)算已執(zhí)行代碼行數(shù)、總代碼行數(shù)以及覆蓋率數(shù)值;然后按照相同邏輯,如果某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)數(shù)據(jù)發(fā)生了變化,則重新計(jì)算,否則不變。最后在根節(jié)點(diǎn)重新結(jié)算總的覆蓋率數(shù)據(jù)即可。
如圖3所示,若節(jié)點(diǎn)“文件Nk”的數(shù)據(jù)發(fā)生了變化,則其兄弟節(jié)點(diǎn)的數(shù)據(jù)保持不變,只需要重新計(jì)算文件Nk節(jié)點(diǎn)、目錄0N節(jié)點(diǎn)以及根節(jié)點(diǎn)的數(shù)據(jù)即可。
本發(fā)明提供的覆蓋率數(shù)據(jù)的處理方法,通過將同一個(gè)服務(wù)器上的文件根據(jù)目錄進(jìn)行樹形結(jié)構(gòu)存儲(chǔ),在覆蓋率數(shù)據(jù)發(fā)送修改時(shí),逐個(gè)節(jié)點(diǎn)查詢只對(duì)該節(jié)點(diǎn)的覆蓋率數(shù)據(jù)進(jìn)行修改,只需要對(duì)改變了的節(jié)點(diǎn)重新計(jì)算,有效減小全局?jǐn)?shù)據(jù)修改和覆蓋率計(jì)算帶來的性能消耗,提高測試效率。即解決了代碼量較大時(shí),全局的數(shù)據(jù)修改和覆蓋率數(shù)據(jù)重新計(jì)算帶來的性能消耗較高的問題。
圖5為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置實(shí)施例一的結(jié)構(gòu)示意圖,如圖5所示,本實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置10包括:
接收模塊11,用于接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù);
處理模塊12,用于查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn);
所述處理模塊12還用于根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
本實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置,用于執(zhí)行前述任一實(shí)施例提供的方法中覆蓋率服務(wù)器的技術(shù)方案,其實(shí)現(xiàn)原理和技術(shù)效果類似,在此不再贅述。
在本發(fā)明覆蓋率數(shù)據(jù)的處理裝置的實(shí)施例二中,圖6為本發(fā)明實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置實(shí)施例二的結(jié)構(gòu)示意圖,如圖6所示,在上述實(shí)施例一的基礎(chǔ)上,該覆蓋率數(shù)據(jù)的處理裝置10還包括:
存儲(chǔ)模塊13,用于將所述第一子節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)更新為所述覆蓋率數(shù)據(jù)。
在上述任一實(shí)施例的基礎(chǔ)上,可選的,所述接收模塊11接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù)之前,所述處理模塊12還用于:
根據(jù)每個(gè)文件的文件名稱和目錄信息建立所述樹形存儲(chǔ)結(jié)構(gòu);其中,所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)下包括至少一層以目錄信息以及文件名稱逐層建立的子節(jié)點(diǎn);
根據(jù)每個(gè)子節(jié)點(diǎn)下的文件的執(zhí)行數(shù)據(jù)計(jì)算獲取與所述子節(jié)點(diǎn)對(duì)應(yīng)的覆蓋率。
可選的,所述處理模塊12具體用于:
通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù);
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),以及每個(gè)與所述第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),計(jì)算獲取所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),將所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)作為第一子節(jié)點(diǎn),重復(fù)本步驟直至計(jì)算出所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)的處的總代碼行數(shù)和已執(zhí)行代碼行數(shù);
根據(jù)所述根節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),計(jì)算獲取所述服務(wù)器的所述總體覆蓋率。
可選的,所述處理模塊12還用于:
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)計(jì)算所述第一子節(jié)點(diǎn)的覆蓋率;
控制將所述第一子節(jié)點(diǎn)的覆蓋率進(jìn)行更新并予以顯示。
本實(shí)施例提供的覆蓋率數(shù)據(jù)的處理裝置,用來執(zhí)行前述任一實(shí)施例提供的方法中覆蓋率服務(wù)器的技術(shù)方案,其實(shí)現(xiàn)原理和技術(shù)效果類似,在此不再贅述。
圖7為本發(fā)明實(shí)施例提供的服務(wù)器實(shí)施例一的結(jié)構(gòu)示意圖,如圖7所示,該服務(wù)器可以被具體實(shí)現(xiàn)為:存儲(chǔ)有程序指令的存儲(chǔ)器21、接收器22和用于控制程序指令執(zhí)行的處理器23;
所述接收器22用于接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù);所述執(zhí)行數(shù)據(jù)包括正在執(zhí)行文件的文件名稱和覆蓋率數(shù)據(jù);
所述處理器23用于:
查詢預(yù)先建立的樹形存儲(chǔ)結(jié)構(gòu)中的每層的節(jié)點(diǎn),獲取與所述文件名稱對(duì)應(yīng)的第一子節(jié)點(diǎn);
根據(jù)所述覆蓋率數(shù)據(jù)和預(yù)先獲取的與第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的覆蓋率數(shù)據(jù),計(jì)算獲取所述服務(wù)器的總體覆蓋率。
可選的,所述存儲(chǔ)器21還用于將所述第一子節(jié)點(diǎn)下存儲(chǔ)的數(shù)據(jù)更新為所述覆蓋率數(shù)據(jù)。
可選的,所述接收器22接收服務(wù)器發(fā)送的執(zhí)行數(shù)據(jù)之前,所述處理器23還用于:
根據(jù)每個(gè)文件的文件名稱和目錄信息建立所述樹形存儲(chǔ)結(jié)構(gòu);其中,所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)下包括至少一層以目錄信息以及文件名稱逐層建立的子節(jié)點(diǎn);
根據(jù)每個(gè)子節(jié)點(diǎn)下的文件的執(zhí)行數(shù)據(jù)計(jì)算獲取與所述子節(jié)點(diǎn)對(duì)應(yīng)的覆蓋率。
可選的,所述處理器23具體用于:
通過所述覆蓋率數(shù)據(jù)以及所述文件名稱對(duì)應(yīng)的源代碼文件,計(jì)算所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù);
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),以及每個(gè)與所述第一子節(jié)點(diǎn)在同一層的其他子節(jié)點(diǎn)的總代碼行數(shù)和已執(zhí)行代碼的行數(shù),計(jì)算獲取所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),將所述第一子節(jié)點(diǎn)所屬的上一層節(jié)點(diǎn)作為第一子節(jié)點(diǎn),重復(fù)本步驟直至計(jì)算出所述樹形存儲(chǔ)結(jié)構(gòu)的根節(jié)點(diǎn)的處的總代碼行數(shù)和已執(zhí)行代碼行數(shù);
根據(jù)所述根節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼行數(shù),計(jì)算獲取所述服務(wù)器的所述總體覆蓋率。
可選的,所述處理器23還用于:
根據(jù)所述第一子節(jié)點(diǎn)處的總代碼行數(shù)和已執(zhí)行代碼的行數(shù)計(jì)算所述第一子節(jié)點(diǎn)的覆蓋率;
控制將所述第一子節(jié)點(diǎn)的覆蓋率進(jìn)行更新并予以顯示。
本實(shí)施例提供的服務(wù)器為覆蓋率服務(wù)器,用來執(zhí)行前述任一實(shí)施例提供的方法的技術(shù)方案,其實(shí)現(xiàn)原理和技術(shù)效果類似,在此不再贅述。
在上述任一服務(wù)器的實(shí)施例中,應(yīng)理解,處理器可以是中央處理單元(英文:Central Processing Unit,簡稱:CPU),還可以是其他通用處理器、數(shù)字信號(hào)處理器(英文:Digital Signal Processor,簡稱:DSP)、專用集成電路(英文:Application Specific Integrated Circuit,簡稱:ASIC)等。通用處理器可以是微處理器或者該處理器也可以是任何常規(guī)的處理器等。結(jié)合本發(fā)明實(shí)施例所公開的方法的步驟可以直接體現(xiàn)為硬件處理器執(zhí)行完成,或者用處理器中的硬件及軟件模塊組合執(zhí)行完成。
本領(lǐng)域普通技術(shù)人員可以理解:實(shí)現(xiàn)上述各方法實(shí)施例的全部或部分步驟可以通過程序指令相關(guān)的硬件來完成。前述的程序可以存儲(chǔ)于一計(jì)算機(jī)可讀取存儲(chǔ)介質(zhì)中。該程序在執(zhí)行時(shí),執(zhí)行包括上述各方法實(shí)施例的步驟;而前述的存儲(chǔ)介質(zhì)包括:只讀存儲(chǔ)器(英文:read-only memory,縮寫:ROM)、RAM、快閃存儲(chǔ)器、硬盤、固態(tài)硬盤、磁帶(英文:magnetic tape)、軟盤(英文:floppy disk)、光盤(英文:optical disc)及其任意組合。
最后應(yīng)說明的是:以上各實(shí)施例僅用以說明本發(fā)明的技術(shù)方案,而非對(duì)其限制;盡管參照前述各實(shí)施例對(duì)本發(fā)明進(jìn)行了詳細(xì)的說明,本領(lǐng)域的普通技術(shù)人員應(yīng)當(dāng)理解:其依然可以對(duì)前述各實(shí)施例所記載的技術(shù)方案進(jìn)行修改,或者對(duì)其中部分或者全部技術(shù)特征進(jìn)行等同替換;而這些修改或者替換,并不使相應(yīng)技術(shù)方案的本質(zhì)脫離本發(fā)明各實(shí)施例技術(shù)方案的范圍。