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