【测试人生】代码覆盖率测试之代码染色优化——以lua代码覆盖为例

在研发代码覆盖率测试工具的时候,通常除了代码覆盖数据收集模块之外,一般还要研发前端展示的部分以展现代码覆盖分析报告,通常会为每一个文件增加行染色,类似于jacoco这种形式。

然而代码覆盖报告实际出来的行染色,会出现许多正常代码行没有着色的情况。这是因为编程语言认为的“行”和本身我们在文本编辑器打出的”行“是不一样的。编译出来的“行”实际上是一段操作,比如我们定义一个函数的时候,编译器认为我们执行的操作有包括function xxx那一行,于是就有一种情况——我们实际没有运行过这个函数,但由于定义被覆盖,因此出现function xxx染绿,而函数体染红的现象。从用户的角度而言,用户如果对代码编译这块并不熟悉的话,就会造成理解上的偏差。

因此考虑工作成本,如果有必要的话,需要对代码覆盖数据进行修改,从而展现更好的代码行染色效果。以lua为例,可以采用这样的方法:

lua代码收集已经在luacov源码分析有相关解读,这块不赘述。在代码编译的语法分析方面有一个经典的方法叫做递归下降法,如果需要测定覆盖率的语言是像lua这样简单的话,就可以直接应用。我们可以从lua文件原始的覆盖数据,推断近乎真实的覆盖数据。首先把一个文件所有的代码分为不同的chunk:

  • main chunk
  • loop end chunk
  • do end chunk
  • (local) function end chunk
  • if elseif else end chunk

而后自顶向下递归下降遍历代码行。我们起始就已经在main chunk,因此理论上来说,main chunk中所有不是其它子chunk的代码都能被覆盖到(当然也包括do end)。而后针对loop、if/elseif/else、function,则采用如下的判断机制:

  • loop内及loop语句本身的代码行覆盖多少次算多少次
  • function内如果一行都没有覆盖,那么function与end声明也算没有覆盖。就算是return function() end也一样,因为用户比较关心这个function实际是否有运行
  • if方面,统计每个if、elseif、else块的代码覆盖,分为三种状态:全部覆盖、部分未覆盖、全部未覆盖。

lua本身是不支持检测if事件的,但实际通过语法分析,可以检测到if代码块,这样我们就可以像jacoco一样,为if代码行染一个不同的颜色。至于代码染色如何标记,其实可以用int32的高几位来标记对应行的颜色就好了,这种方法在做增量覆盖的情况下也适用。

如果出现xxx end在同一行的情况,那就更好办了,该覆盖几次是几次。

假定程序员写代码写的比较规范的话,用这种方法进行行染色展现代码覆盖报告,效果可是真的杠杠的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我们可以使用 Lua 脚本来优化这段代码,避免了 Redis 命令的网络延迟和多次通信的开销,提高了秒杀的并发能力。 首先,我们需要将秒杀的逻辑封装到一个 Lua 脚本中。在这个脚本中,我们可以使用 Redis 的 `watch` 命令来监视商品的库存数量,如果库存数量发生变化,则取消脚本的执行。然后,我们可以使用 Redis 的 `multi` 命令来开启一个事务,将库存数量减一,并将秒杀成功的信息写入 Redis 中,并最终提交这个事务。 ```lua -- KEYS[1] 为商品库存数量的键名 -- KEYS[2] 为秒杀成功用户列表的键名 -- ARGV[1] 为用户 ID if redis.call("get", KEYS[1]) > 0 then redis.call("watch", KEYS[1]) redis.call("multi") redis.call("decr", KEYS[1]) redis.call("rpush", KEYS[2], ARGV[1]) return redis.call("exec") else return 0 end ``` 然后,我们可以在 PHP 代码中调用这个 Lua 脚本,使用 Redis 的 `eval` 命令来执行这个脚本。 ```php $lua_script = <<<LUA -- 上面的 Lua 脚本 LUA; $goods_count_key = 'goods_count'; $user_list_key = 'user_list'; $user_id = $_SESSION['user_id']; $result = $redis->eval($lua_script, [$goods_count_key, $user_list_key, $user_id], 2); if ($result) { echo '秒杀成功'; } else { echo '秒杀失败'; } ``` 在上面的代码中,`$redis->eval()` 方的第一个参数是 Lua 脚本的内容,第二个参数是 Lua 脚本中使用的键名和参数值,第三个参数是键名的数量,也就是 `KEYS` 数组的长度。 使用 Lua 脚本可以将秒杀的逻辑封装到一个原子性操作中,避免了并发问题,并且可以减少 Redis 命令的网络延迟和多次通信的开销,提高了秒杀的并发能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值