OpenResty单元测试实践

2016-10-25   出处: segmentfault  作/译者:spacewander

无测试,不编码。有持续运行的单元测试,是保持项目健康最基本的要求。在多人协作的内部项目中,这一点尤其重要。基于 OpenResty 的项目开发自然不会例外。

测试框架

我们考察过 OpenResty 自己的测试框架test-nginx,发现该框架偏向于对接口进行测试。把它用作单元测试,犹如用园艺剪裁纸。
以 lua 应用的角度看,busted倒是个合适的单元测试框架。只是 OpenResty 项目代码中难免会用到 OpenResty 的 API。
如果不能在 OpenResty 上下文中运行测试,那么这些 API 就无法调用。显然我们不可能把这些 API 都分离出去,或者 mock 掉。
这么做不切实际。

好在 OpenResty 提供了resty命令行工具,能够以一次性命令的形式在 OpenResty 上下文运行给定的 lua 代码。
结合resty和busted两个工具,有一个办法可以在 OpenResty 上下文中运行 busted 的测试代码。

首先,注意要安装 lua5.1 对应的 luarocks。luarocks 默认的 lua 版本是 5.2, 所以安装的时候需要配置一下。如果能够像这样,直接指定使用安装 OpenResty 时附带的 luajit,那就更好了:

 

然后sudo luarocks install busted, 安装 busted。

查看命令行工具 busted 的内容,会发现它其实是个启动脚本:

 

OK,现在就让 resty 去执行这个脚本吧!

假设项目结构如下:

 

我们可以这样运行:

 

解释下,-I参数后面跟着的是 lua 模块的路径,-e参数后面跟着的是要执行的代码片段,--
后面是用户参数。所以上面的命令等价于busted --verbose test_spec.lua。

使用resty来运行 lua 代码有一个局限。它会在ngx.timer的上下文运行代码,导致许多跟请求上下文相关的 OpenResty API
依然是无法调用的。举个例子,如果待测试代码里面调用了ngx.location.capture,执行测试会得到这样的结果:

 

不过这已足矣,毕竟我们是在做单元测试而非接口测试。像是请求上下文的东西,就应该在测试时 mock 掉。至于怎么 mock,这属于busted 的范畴,请参考 busted 的文档。

测试覆盖

有了测试,下面的需求就是统计测试的覆盖。

假若有具体的测试覆盖程度,程序员们可以针对性地编写测试,对哪些地方缺乏测试也心知肚明。
另外,还可以求出项目的测试覆盖率。
测试覆盖率不仅仅能够衡量项目的健康程度。覆盖率的增增减减,会激励程序员们尽可能地多写测试。
谁会愿意看着自己新增的代码一片红色(无测试覆盖)?自然而然的,如果每次提交的时候,可以及时获得测试覆盖的反馈,便能保持一个较高的覆盖率。

在 lua 中有一个库 luacov ,可以实现这样的功能。
在测试运行时加入 luacov ,它会在每一行加入钩子函数,触发对测试覆盖的统计。luacov 会把统计到的覆盖率报告在
luacov.stats.out文件中。
busted已经内置了 luacov 支持,所以我们要操心的事情就少很多。

需要往前面的 busted 命令添加--coverage选项:

 

为了让 luacov 能够写出覆盖报告,还需要在.luacov下配置:

 

如果不这么做,我们就没办法获取测试覆盖结果了。因为 luacov 默认只在程序退出时才写入覆盖报告,而我们的 openresty
是作为后台程序运行的。设置了tick = true后,luacov 会定期更新覆盖报告。除了tick,你还可以在.luacov
中设置许多 luacov 相关的配置:
http://keplerproject.github.i...

现在已经有了份luacov.stats.out了,它长这样:

 

显然,这一份不是人类可读的版本。

接着运行luacov YOUR_SRC_DIR可以生成出luacov.report.out。
这一份就是最终的测试覆盖率报告:

 

当然这一份也不怎么“对人类友好”。如果嫌 luacov 默认生成的报告太粗糙,可以使用第三方的 reporter:
https://github.com/keplerproj...

或者,自己动手,丰衣足食:造一个 reporter 轮子。
这方面没有什么文档,只能去读luacov 默认的 reporter 实现
另外一个思路是,写个脚本去解析生成的luacov.report.out测试报告,去生成更加可视化的版本(或者跟现有的 CI 平台对接)。


声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
403° /4035 人阅读/0 条评论 发表评论

登录 后发表评论