能否让Test::More报告Perl测试中间接调用者的行号?
解决Test::More显示间接调用者行号的问题
要让Test::More在测试失败时显示**间接调用者(如main中调用complex_test的行号)**而非直接调用ok()的子例程行号,核心是调整Test::Builder的caller_level属性,让它跳过中间的封装子例程,从调用栈的更上层获取行号信息。
具体实现方法
修改你的foo_OK子例程,临时调整caller_level,执行测试后再恢复原有层级:
#!/usr/bin/perl use 5.18.2; use warnings; use strict; use Test::More; sub foo(@) { # do something magical return undef; } sub foo_OK(@) { my $tb = Test::More->builder; # 保存原始调用层级,避免影响其他测试 my $original_level = $tb->caller_level; # 增加2层,跳过foo_OK和complex_test,指向main中的调用行 $tb->caller_level($original_level + 2); ok(foo(@_), 'foo_OK: ' . join(' ', @_)); # 恢复原始调用层级 $tb->caller_level($original_level); } sub complex_test(@) { foo_OK(qw(something special), @_); foo_OK(qw(something else), @_); #... } sub main() { complex_test(qw(abra kadabra)); # 假设这是第28行 complex_test(qw(more magic)); # 假设这是第29行 #... } main(); done_testing();
修改后的输出效果
运行后,失败测试的行号会指向main中调用complex_test的行:
not ok 1 - foo_OK: something special abra kadabra # Failed test 'foo_OK: something special abra kadabra' # at /tmp/test.pl line 28. not ok 2 - foo_OK: something else abra kadabra # Failed test 'foo_OK: something else abra kadabra' # at /tmp/test.pl line 28. not ok 3 - foo_OK: something special more magic # Failed test 'foo_OK: something special more magic' # at /tmp/test.pl line 29. not ok 4 - foo_OK: something else more magic # Failed test 'foo_OK: something else more magic' # at /tmp/test.pl line 29. 1..4 # Looks like you failed 4 tests of 4.
原理说明
Test::More的所有测试函数(如ok)都依赖Test::Builder模块跟踪调用栈。caller_level属性决定了从调用栈的哪一层提取文件名和行号:
- 默认值为1,对应直接调用
ok的子例程(即foo_OK)的行号 - 增加该值时,会跳过中间的调用层级,指向更上层的代码(这里+2跳过了
foo_OK和complex_test,直接指向main中的调用行)
如果后续有更多层级的封装,只需调整+N中的N值,确保指向你需要的调用行即可。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

