您的位置:首页 > 编程语言 > Lua

lua开源测试框架busted源码学习(-)----outputHandlers模块

2016-11-14 18:56 991 查看
项目中用到了lua的单元测试框架busted,根据需求需要对busted源码进行分析,这次主要分析一下outputHandlers模块。

项目的地址见:点击打开链接

默认busted的输出见runner.lua:如下两行代码。

options = tablex.update(require 'busted.options',options or {})
options.output = options.output or (isatty and 'utfTerminal' or 'plainTerminal')

options是命令行读进来的一些参数。如果命令行参数为空,options.output  则会返回(isatty and 'utfTerminal' or 'plainTerminal')

isatty简单来说就是检测给定的文件描述符是否链接到一个终端,因为lua中的io库中io.stdin、io.stdout以及io.stderr是默认提供的预定义的句柄,所以isatty为true,那么最终的options.output就会取utfTerminal或者plainTerminal。

tablex.updata可以在/usr/local/share/lua/5.3/pl/tablex.lua中看到,其实就是表拷贝的过程,tablex.lua的位置可以root  用find 命令查找;
function tablex.update (t1,t2)
assert_arg_writeable(1,t1)
assert_arg_iterable(2,t2)
for k,v in pairs(t2) do
t1[k] = v
end
return t1
end当然,如果加了 -o  /busted/outputHandlers/xxx.lua,那么在output_handler_loader.lua中会调用:
handler = require('busted.outputHandlers.' .. output)这样最终会按照读取的格式进行显示输出。

outputHandlers目录下最重要的文件就是base.lua,其他就是不同输出格式的lua文件,包括gtest.lua、json.lua、junit.lua、plainTerminal.lua、sounds.lua、TAP.lua以及utfTerminal.lua。虽然格式文件多,但是查看代码,都包括以下三部分内容:

1.busted和handler的引入

local busted = require("busted")
local handler = require("busted.outputHandler.base")()

2.定制自己的输出函数
handler.testStart = function(element, parent)
-----xxxxxxx
end
handler.testEnd = function(element, parent, status, trace)
--xxxxxxxxxxxxxx
end

3.subscribe自定义的函数
busted.subscribe({'test', 'start'}, handler.testStart)
busted.subscribe({'test', 'end'}, handler.testEnd)
这样就可以完成定制格式的输出;

其实outputHandlers模块有策略模式的影子,base.lua可以看成是strategy基类,gtest.lua等可以看成是不同的策略实现,”继承”于base.lua。base.lua中需要根据格式进行重写的方法包括:

busted.subscribe({ 'suite', 'reset' }, handler.baseSuiteReset, { priority = 1 })
busted.subscribe({ 'suite', 'start' }, handler.baseSuiteStart, { priority = 1 })
busted.subscribe({ 'suite', 'end' }, handler.baseSuiteEnd, { priority = 1 })
busted.subscribe({ 'test', 'start' }, handler.baseTestStart, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'test', 'end' }, handler.baseTestEnd, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'pending' }, handler.basePending, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'failure', 'it' }, handler.baseTestFailure, { priority = 1 })
busted.subscribe({ 'error', 'it' }, handler.baseTestError, { priority = 1 })
busted.subscribe({ 'failure' }, handler.baseError, { priority = 1 })
busted.subscribe({ 'error' }, handler.baseError, { priority = 1 })

可以查看busted.subcribe,在core.lua文件中
function busted.subscribe(...)
return mediator:subscribe(...)
end继续跟进在term/mediator.lua中可以看到mediator:subscribe的代码,其实就是在callback中添加回调函数(这块函数后续将继续分析)
subscribe = function(self, channelNamespace, fn, options)
return self:getChannel(channelNamespace):addSubscriber(fn, options)
end,
addSubscriber = function(self, fn, options)
local callback = Subscriber(fn, options)
local priority = (#self.callbacks + 1)

options = options or {}

if options.priority and
options.priority >= 0 and
options.priority < priority
then
priority = options.priority
end

table.insert(self.callbacks, priority, callback)

return callback
end,


重写了之后,运行时调用的就是定义的方法而不是base.lua中的基类方法,这也可以看成是一种继承;

base.lua中提供了一个handler表,记录测试中出现的失败、错误以及成功等的信息,持有的方法包括:
handler.cancelOnPending
handler.subscribe
handler.getFullName
handler.format
handler.getDuration
handler.baseSuiteStart
handler.baseSuiteReset
handler.baseSuiteEnd
handler.baseTestStart
handler.baseTestEnd
handler.basePending
handler.baseTestFailure
handler.baseTestError
handler.baseError

其中handler.format方法即将每个用例的信息进行格式化的一个过程,format中持有一个表formatted
local formatted = {
trace = debug or element.trace,
element = copyElement(element),
name = handler.getFullName(element),
message = message,
randomseed = parent and parent.randomseed,
isError = isError
}这张表会保存每个element的信息,包括状态、调试信息、名称等;然后根据测试结果的不同将formatted表insert到不同的表中,最后再做不同的处理。
table.insert(handler.failures, handler.format(element, parent, message, debug))
table.insert(handler.errors, handler.format(element, parent, message, debug, true))
table.insert(insertTable, formatted)


上述是看代码过程中的一点笔记,也还存在一些不太懂的地方,需要结合busted源码其他的文件进行深入;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua 单元测试 busted