设为首页 加入收藏

TOP

[lua][openresty]代码覆盖率检测的解决方式(一)
2019-09-17 17:12:32 】 浏览:46
Tags:lua openresty 代码 覆盖率 检测 解决 方式

废话在前

什么是代码覆盖率

来自百度百科

代码覆盖(Code coverage)是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率。

开发人员为何关注?

在我们的开发过程中,经常要用各种方式进行自测,或是各种 xUnit 系列,或是 postman,或是直接curl,在我们的代码交给 QA 同学之前,我们有必要知道自己的自测验过了多少内容,在这种情况,代码覆盖率就是一个重要的衡量指标。

openresty 中的代码覆率解决方案

我们如果想得到每一次执行的代码覆率,需要搞定两件事情:

  1. 可以外在的记录每一行的代码
  2. 在记录的同时,可以知道这一行的代码上下文是什么
  3. 更重要的是,我们需要尽可能的不动现有业务代码

对于第一点,lua的debug库中有一个非常神奇的钩子函数sethook,其官方文档如下:

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

Sets the given function as a hook. The string mask and the number count describe when the hook will be called. The string mask may have any combination of the following characters, with the given meaning:

  • 'c': the hook is called every time Lua calls a function;
  • 'r': the hook is called every time Lua returns from a function;
  • 'l': the hook is called every time Lua enters a new line of code.Moreover, with a count different from zero, the hook is called also after every count instructions.

When called without arguments, debug.sethook turns off the hook.
When the hook is called, its first argument is a string describing the event that has triggered its call: "call" (or "tail call"), "return", "line", and "count". For line events, the hook also gets the new line number as its second parameter. Inside a hook, you can call getinfo with level 2 to get more information about the running function (level 0 is the getinfo function, and level 1 is the hook function).

其中文翻译大体如下:

将给定的方法设定为钩子,参数maskcount决定了什么时候钩子方法被调用.参数mask可以是下列字符的组合:

  • 'c' 当lua开始执行一个方法时调用;
  • 'r' 当lua执行一个方法在返回时调用;
  • 'l' 当lua每执行到一行代码时调用.即lua从0开始执行一个方法的每一行时,这个钩子都会被调用.

如果调用时不传任何参数,则会移除相应的钩子.当一个钩子方法被调用时,第一个参数表明了调用这个钩子的事件:"call"(或"tail call"),"return","line""count".对于执行代码行的事件,新代码的行号会作为第二个参数传入钩子方法,可以用debug.getinfo(2)得到其他上下文信息.

在这个官方的说明里,lua已经贴心的告诉我们使用方式————配合debug.getinfo,那么debug.getinfo是什么?其实我们在之前讨论错误输出时已经使用过这个方法,其官方文档如下:

debug.getinfo ([thread,] f [, what])

Returns a table with information about a function. You can give the function directly or you can give a number as the value of f, which means the function running at level f of the call stack of the given thread: level 0 is the current function (getinfo itself); level 1 is the function that called getinfo (except for tail calls, which do not count on the stack); and so on. If f is a number larger than the number of active functions, then getinfo returns nil.

The returned table can contain all the fields returned by lua_getinfo, with the string what describing which fields to fill in. The default for what is to get all information available, except the table of valid lines. If present, the option 'f' adds a field named func with the function itself. If present, the option 'L' adds a field named activelines with the table of valid lines.

For instance, the expression debug.getinfo(1,"n").name returns a name for the current function, if a reasonable name can be found, and the expression debug.getinfo(print) returns a table with all available information about the print function.

这个API的说明中文含义大体如下:

以table的形式返回一个函数的信息,可以直接调用这个方法或是传入一个表示调用堆栈深度的参数f,0表示当前方法(即getinfo本身),1表示调用getinfo的方法(除了最顶层的调用,即不在任何方法中),以此类推。如果传入的值比当前堆栈深度大,则返回nil.

返回的table内字段包含由lua_info返回的所有字段。默认调用会除了代码行数信息的所有信息。当前版本下,传入'f'会增加一个func字段表示方法本身,传入'L'会增加一个activelines字段返回函数所有可用行数。

例如如果当前方法是一个有意义的命名,debug.getinfo(1,"n")

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Zookeeper核心原理 下一篇springMVC_07乱码及restful风格

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目