【Lua】实现代码执行覆盖率统计工具

2021-11-28

一、如何评估测试过程的测试情况?

    很多时候完成功能测试后就会发布上线,甚至交叉和回归都没有足够的时间去执行,然后通过线上的补丁对遗漏的问题进行修复。如果可以在发布前了解本次测试过程所覆盖代码执行的比例情况,那么就可以一定程度上反应测试的执行情况和系统的质量情况。

    代码执行覆盖率是一种很好评估测试人员在执行测试过程中,所命中技术编码情况的手段,并可以从侧面评估系统的质量情况。我所在的项目前后端都是用Lua进行逻辑业务开发,这里分享如何使用Lua的debug模块进行代码执行覆盖率统计的实现。

 

二、Lua代码执行覆盖统计工具

    代码覆盖率可以做到行覆盖率,函数覆盖率和分支覆盖率。通过Lua语言debug库的sethook方法可以设置以行或以函数来监控代码的执行行为。

debug.sethook ([thread,] hook, mask [, count]):

    可以通过官方文档获得更好的介绍,这里通过设置回调函数和监控的方式,然后在监控的回调函数里面记录当前执行的文件及执行的行数、以及函数记录。最后在停止hook的时候将上面记录数据输出到文本文件,这样就可以知道本次测试在运行过程中所有代码执行的情况记录。

 1 function call_hook_func()
 2     local info = debug.getinfo(2, "nlS")
 3     if not info then
 4         return
 5     end
 6     local filename = info.short_src
 7     local linenum = info.currentline
 8     local func = info.name   -- 函数名
 9     -- 过滤掉C层调用
10     if linenum <= 0 then return end
11     -- 文本函数记录表 g_code 记录文件名,行数,函数名和执行的次数
12     local file_line_tb = g_code[filename]
13     if not file_line_tb then
14         file_line_tb = {}
15         g_code[filename] = file_line_tb
16     end
17     -- 这里是行数
18     local func_info = file_line_tb[linenum]
19     if not func_info then
20         func_info = {[0]=0, [1]=func}
21         file_line_tb[linenum] = func_info
22     end
23     -- 统计执行的次数
24     func_info[0] = (func_info[0] or 0) + 1
25 end
26 debug.sethook(call_hook_func, "c")

 以上是简单的函数执行统计的代码,通过设置hook函数调用,在监控函数里面统计当前执行的文件、所在行、以及函数,并且还记录了这个函数的执行次数。这样就可以得到原始的代码执行情况的数据记录。通过编写一个分析脚本将执行的数据和源代码的数据进行对比,从而就可以计算出行覆盖率,函数覆盖率,以及分支覆盖率。这样每次在测试执行前开启,在测试结束后统计计算,就可以评估本次测试所覆盖的代码量,甚至可以做更深入的分析判断哪些核心的逻辑没有执行到。

 

三、Lua监控代码执行情况的项目仓库

https://github.com/memolp/LuaCodeCoverage

使用方法:

    1. 导入模块

require "CodeCoverage" 

    2. 执行Hook,并选择统计的类型(这里提供基于行的统计和基于函数的统计)

-- Jeff_CodeCoverage.LINE_COVERAGE_MODE 行覆盖率统计
-- Jeff_CodeCoverage.FUNC_COVERAGE_MODE 函数覆盖率统计
-- StartHook 第二个参数设置为true将实时输出行或函数覆盖的执行流数据
Jeff_CodeCoverage.StartHook(Jeff_CodeCoverage.FUNC_COVERAGE_MODE)

    3. 测试完业务功能后,调用停止Hook,输出本次执行的数据

Jeff_CodeCoverage.StopHook()

    4. 通过上面输出的数据,与源码进行对比计算出覆盖率。(这里需要开发一个统计源代码行数和函数的工具)。