目前針對於高級語言如C++,JAVA,C#等工程都有相關的代碼覆蓋率統計工具,可是對於oracle存儲過程或者數據庫sql等方面的項目,代碼覆蓋率統計和掃描工具相對較少。java
所以針對這種狀況,設計了代碼覆蓋率統計工具,其實oracle已經提供了較好的代碼profiler包,本文主要介紹利用DBMS_PROFILER設計的代碼覆蓋率統計工具。git
1.代碼打樁github
獲取代碼覆蓋率的前提是,須要對被測代碼進行profiler,也就是打樁,須要有一個計數器去統計被執行到的代碼行。Oracle提供了一個有用的工具包叫DBMS_PROFILER。經過這個包咱們能夠對被測的SP代碼進行打樁,這個包不但能夠獲取被執行的代碼行,並且還能夠統計出代碼執行的時間,也是用來作代碼調優的有用工具。sql
工具包的使用也很方便:數據庫
plsql_profiler_runs :運行記錄,最重要字段爲runid。bootstrap
plsql_profiler_units: 每次runid對應的各個unit的通常信息oracle
plsql_profiler_data:每次runid對應的各個unit具體line的詳細信息工具
在PL/SQL開頭結尾添加便可單元測試
begin測試
DBMS_PROFILER.START_PROFILER('PLSQLNAME:'||TO_CHAR(SYSDATE,'YYYY-MM-DD HH:MI:SS'));
pl/sql statements;
DBMS_PROFILER.STOP_PROFILER;
end;
經過上述過程,測試人員在作手工測試執行以前,須要先對要測試的代碼進行打樁,或者能夠經過plsql來對代碼進行打樁。而開發人員在作單元測試的時候能夠對本身的sp代碼進行打樁。
須要從如下三張表中收集代碼覆蓋率數據:
All_source:
plsql_profiler_units:
plsql_profiler_data:
經過如下sql能夠彙總覆蓋率數據:
SELECT u.UNIT_OWNER || '.' || u.UNIT_NAME AS "Unit", s.line, CASE WHEN d.TOTAL_OCCUR >= 0 THEN 'C' ELSE '0' END AS Covered, s.TEXT, TO_CHAR(d.TOTAL_TIME / (1000*1000*1000), 'fm990.000009') AS "Total Time (sec)", CASE WHEN NVL(d.TOTAL_OCCUR, 1) > 0 THEN d.TOTAL_OCCUR ELSE 1 END AS "# Iterations" , TO_CHAR(CASE WHEN d.TOTAL_OCCUR > 0 THEN d.TOTAL_TIME / (d.TOTAL_OCCUR * (1000*1000*1000))ELSE 0.0000 END, 'fm990.000009') AS "Avg Time (sec)" FROM all_source s LEFT JOIN plsql_profiler_units u ON s.OWNER = u.UNIT_OWNER AND s.NAME = u.UNIT_NAME AND s.TYPE = u.UNIT_TYPE LEFT JOIN plsql_profiler_data d ON u.UNIT_NUMBER = d.UNIT_NUMBER AND s.LINE = d.line# AND d.RUNID = u.RUNID WHERE u.unit_owner NOT IN ('SYSTEM','ULOG','<anonymous>') and s.TYPE not in ('PACKAGE SPEC')ORDER BY u.UNIT_NAME, s.LINE
獲得以下圖所示數據。
視圖中Unit這個字段爲存儲過程的包名,covered這個字段中如果用代碼被執行到就會被賦值爲」C」,該字段的值主要是經過plsql_profiler_data中的total_occur這個字段的值來獲取的,這個字段的值要是大於1那麼,上圖Iterations的值等於total_occur表示改行代碼被執行的次數。此外視圖中還有一些關於代碼執行所花費的整體執行時間和平均執行時間的計算。
能夠經過計算covered字段中」c」值的整體個數除以包中代碼總行數來計算包中代碼的行覆蓋率。因爲代碼覆蓋率的計算公式爲:執行代碼行數(executed lines)/整體代碼行數(total lines)*100。所以若要提升代碼覆蓋率,能夠經過下降整體代碼行數或者增長執行代碼行數,其中下降整體代碼行數須要結合技術公司開發規範,如哪些代碼是不須要被統計到整體代碼行數中的。而增長執行代碼行數則須要測試人員或者開發人員豐富測試用例來覆蓋相關的代碼行。這樣才能獲得一個比較科學的代碼行覆蓋率。
本次代碼覆蓋率工具的收集在第一階段只能作到代碼行覆蓋,須要結合公司的開發規範進行統計。
3. 報告生成
主要經過java+bootstrap+cli等工具,封裝生成基於命令行操做的代碼覆蓋率報告生成工具,首頁展現全部package中sp整體的覆蓋率信息,覆蓋率計算經過analyzed lines/Total lines得出。點擊每一個package能夠獲得具體的覆蓋率信息。
詳細報告中能夠看到具體代碼覆蓋狀況,紅色表示沒有被覆蓋到,其中ave time表示代碼執行的平均時間。
目前這個版本數據庫代碼覆蓋率工具還不夠成熟,如DBMS_PRFILER不會剔除空行代碼的執行,可是在覆蓋率工具中咱們已經剔除了空行,還有針對多行的sql,只會在第一行標上被覆蓋,其實整句sql也就是說269如下的代碼行都應該被覆蓋,這就須要覆蓋率工具須要去作些代碼解析的工做,判斷哪些代碼應該被覆蓋,以下圖所示:
目前數據庫代碼覆蓋率工具才完成第一個版本,後期會將代碼開源到github.