当项目功能开发完毕时,我们常常为了保证自己代码的功能正常,符合自己的预期结果而编写单元测试,并且以后当我们修改代码后,只需要跑一边单元测试便可以看我们有没有把代码给改残了。所以单元测试的重要性不言而喻。

使用不同的编程语言编写代码时,通常都有不同的单元测试框架。而当我们编写OpenResty项目时,比较好用的的测试框架还是比较少等,因为之前一直在看《OpenResty 最佳实践》一书,里面作者自己开发了一套测试框架lua-resty-test,使用后感觉还不错,便在项目中使用了一下。下面大概总结下使用心得。

Nginx 配置添加测试服务器

在配置文件中新增一个专门用于跑单元测试的服务器,并且将它的错误日志专门用另一个test_error.log文件存储。然后新建一个test文件夹用于放置单元测试代码,设置执行单元测试的主入口文件为main.lua
这里别忘了设置下lua_package_path的值,把lua-resty-test的路径加上去。因为我吧项目的一些公共库都放置在了lualib下,所以我的lua_package_path设置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
# conf/nginx.conf
lua_package_path '${prefix}project/?.lua;${prefix}lualib/?.lua;;';
# 新增的单元测试服务器配置
server {
listen 8090;
access_log off;
# 此处修改单元测试服务器的错误日志为test_error.log,有别于开发项目的 error.log文件
error_log logs/test_error.log error;
# 主入口文件为 mian.lua
location /test {
content_by_lua_file 'test/main.lua';
}
}

在主入口文件中加载各个单元测试代码

因为我这里是按照一个文件编写一个单元测试的,所以在主入口文件中进行加载每一个要被测试的代码,代码如下

1
2
3
4
5
6
# test/main.lua
local iresty_test = require "resty.iresty_test"
-- 测试项目中的utils.lua文件
require("test.test_utils.test_utils")(iresty_test)
-- 测试项目中的transac.lua文件
-- require("test.test_controller.test_transac")(iresty_test)

utils 文件的单元测试代码大致如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 # test/test_utils/test_utils.lua

local utils = require("utils.utils")
local cjson = require("cjson")

local function test_utils( iresty_test )

-- 设置此模块的单元测试名称
local test_utils = iresty_test.new({unit_name="test_utils"})

-- init方法可以在跑单元测试的时候执行一些初始化的操作
--function test_utils:init( )
-- self:log("init complete")
--end

-- 测试utils模块的isDigit函数
function test_utils:test_isDigit()
-- case one
local result = utils.isDigit()
local expect = false
assert(expect == result, "isDigit function should return false")

-- case two
local result = utils.isDigit("")
local expect = false
assert(expect == result, "isDigit function should return false")

-- case three
local result = utils.isDigit("12345")
local expect = true
assert(expect == result, "isDigit function should return true")

-- case four
local result = utils.isDigit("123abc")
local expect = false
assert(expect == result, "isDigit function should return true")
end

-- 测试utils模块的trim函数
function test_utils:test_trim()
-- log方法用于记录单元测试的时候,一些日志数据
-- self:log("ok")
end

-- 运行此文件的单元测试
test_utils:run()
end

return test_utils

运行单元测试代码

建议在命令行中使用curl命令,这样的话可以比较明显的看出不同颜色的输出日志

1
curl http://10.100.157.198:8090/test

输出效果如下

1
2
3
4
0.000 [test_utils] unit test start
0.000 \_[test_isDigit] PASS
0.000 \_[test_trim] PASS
0.000 [test_utils] unit test complete