目前针对于高级语言如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.