【问题标题】:Testing code immediately invoked in a script在脚本中立即调用的测试代码
【发布时间】:2016-09-05 19:24:52
【问题描述】:

我目前正在使用 Busted 为 lua mod 库编写单元测试。有问题的文件定义了一个带有一些函数的模块,然后在底部调用其中一个函数来初始化自身。

我发现的问题是 Busted 似乎两次评估所需的文件。

测试

it('does a thing', function()
    -- Some setup, replacing globals etc
    require('items')
    assert.are_equal(2, #Items._registry)
end)

模块

Items = { _registry = {} }
function Items.do_some_stuff() end
function some_util_func() end
function load_registry()
  print(debug.traceback())
  for i, itm in pairs(Items.do_some_stuff()) do
    Items._registry[i] = itm
  end
end

load_registry()

如您所见,虽然我已经简化了代码和名称,但结构并没有什么意外(据我所知)。

测试将始终失败,因为#Items._registry 始终为 0(并且转储到控制台可以验证这一点)。我尝试在方法内部打印,发现它打印了两次;然后我尝试在该功能的顶部使用 debug.traceback 并找到以下内容。如您所见,堆栈回溯打印了两次,表明代码被评估了两次。

这是其他人遇到过的吗?我的测试结构是否适合这种情况?或者这是一个错误?


stack traceback:
    items.lua:96: in function 'load_registry'
    items.lua:109: in main chunk
    [C]: in function 'require'
    spec/items_pec.lua:50: in function <spec/items_spec.lua:39>
    [C]: in function 'xpcall'
    /usr/local/share/lua/5.2/busted/core.lua:178: in function 'safe'
    /usr/local/share/lua/5.2/busted/init.lua:40: in function 'executor'
    /usr/local/share/lua/5.2/busted/core.lua:312: in function </usr/local/share/lua/5.2/busted/core.lua:312>
    [C]: in function 'xpcall'
    /usr/local/share/lua/5.2/busted/core.lua:178: in function 'safe'
    ...
    /usr/local/share/lua/5.2/busted/core.lua:312: in function 'execute'
    /usr/local/share/lua/5.2/busted/block.lua:155: in function 'execute'
    /usr/local/share/lua/5.2/busted/init.lua:7: in function 'executor'
    /usr/local/share/lua/5.2/busted/core.lua:312: in function </usr/local/share/lua/5.2/busted/core.lua:312>
    [C]: in function 'xpcall'
    /usr/local/share/lua/5.2/busted/core.lua:178: in function 'safe'
    /usr/local/share/lua/5.2/busted/core.lua:312: in function 'execute'
    /usr/local/share/lua/5.2/busted/execute.lua:58: in function 'execute'
    /usr/local/share/lua/5.2/busted/runner.lua:174: in function </usr/local/share/lua/5.2/busted/runner.lua:11>
    /usr/local/lib/luarocks/rocks/busted/2.0.rc12-1/bin/busted:3: in main chunk
    [C]: in ?
stack traceback:
    items.lua:96: in function 'load_registry'
    items.lua:109: in main chunk
    [C]: in function 'require'
    spec/items_spec.lua:15: in main chunk
    [C]: in function 'xpcall'
    /usr/local/share/lua/5.2/busted/core.lua:178: in function 'safe'
    /usr/local/share/lua/5.2/busted/block.lua:146: in function 'execute'
    /usr/local/share/lua/5.2/busted/init.lua:7: in function 'executor'
    /usr/local/share/lua/5.2/busted/core.lua:312: in function </usr/local/share/lua/5.2/busted/core.lua:312>
    [C]: in function 'xpcall'
    /usr/local/share/lua/5.2/busted/core.lua:178: in function 'safe'
    /usr/local/share/lua/5.2/busted/core.lua:312: in function 'execute'
    /usr/local/share/lua/5.2/busted/execute.lua:58: in function 'execute'
    /usr/local/share/lua/5.2/busted/runner.lua:174: in function </usr/local/share/lua/5.2/busted/runner.lua:11>
    /usr/local/lib/luarocks/rocks/busted/2.0.rc12-1/bin/busted:3: in main chunk
    [C]: in ?

【问题讨论】:

  • 很难判断这里发生了什么,因为您的堆栈跟踪与您的简化代码无关,而且我们不知道 load_registry 的作用。我建议使用新样式重构您的模块:lua-users.org/wiki/ModulesTutorial
  • 公平点。我为 load_registry 函数添加了一个实现,并编辑了堆栈跟踪中的名称以匹配示例。
  • 我已经在本地尝试了你的示例,但我只得到一个输出,你正在运行什么命令来测试,是否还有其他代码可能会导致问题?
  • 我在 Win 10 机器上运行 busted -t test_in_question -o plainTerminal。这通过新的 Linux 子系统和 Lua 的标准 Windows 安装来实现。被测模块导入了 2 个额外的模块,但是这 2 个模块是由规范提前导入的,并且它们暴露的全局变量被模拟为 _G.A = { some_func }。导入此模块的唯一其他地方是对其功能的测试(我已将其加载行为的测试分离到单独的规范中)但是通过使用 -t 标志运行,我应该运行确切的测试只有,对吧?

标签: unit-testing lua lua-busted


【解决方案1】:

这个问题的答案包含了一些我认为无关紧要的细节,但事实并非如此(请参阅我的comment)。

特别是,我将模块加载行为的测试与其各种功能的测试分开。即使使用busted -t 运行以针对特定测试,被测模块的导入也在两个规范中进行评估;即使 require 调用被放置在根 describe 块的 setup 函数中。

通过合并两个规范,我能够解决这种双重加载问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2021-05-18
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 2011-06-28
    • 2014-09-18
    相关资源
    最近更新 更多