【问题标题】:Test::Most - report failed test with stacktraceTest::Most - 使用堆栈跟踪报告失败的测试
【发布时间】:2015-01-04 00:57:54
【问题描述】:

我正在修复一个大型测试脚本(> 1000 行),它使用一些实用方法(也 > 1000 行)对各种初始数据设置执行重复测试。这有助于整合代码。但是,当测试失败时,它会报告实用方法内部的行号,因此很难追踪哪个测试失败。

是否可以将Test::Most 配置为在测试失败时提供堆栈跟踪而不是仅提供单个行号?

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;

use Test::Most tests => 3;

ok(1, 'first test');

note "The following includes a failed test, but a stack trace would be more helpful";

helper_sub_with_test();       # Line 13

ok(1, 'third test');

sub helper_sub_with_test {
    ok(0, "second test");     # Line 17
}

输出:

$ perl scratch.pl 
1..3
ok 1 - first test
# The following includes a failed test, but a stack trace would be more helpful
not ok 2 - second test
#   Failed test 'second test'
#   at scratch.pl line 17.
ok 3 - third test
# Looks like you failed 1 test of 3.

如您所见,如果失败的测试同时报告了第 17 行和第 13 行,这将有助于对实用程序方法进行多次调用。

【问题讨论】:

  • use Carp::Always ?
  • @mob,Test::Builder 不会通过warn/die 输出其诊断信息。它只是对 STDERR 执行print,所以 Carp::Always 无法钩住它。
  • @Miller 而不是堆栈跟踪,请考虑使用islikeis_deeply 而不仅仅是ok 提供更多诊断信息。使用explain 可以提供更多诊断信息。成语ok $something || explain $complex_data 很有用。如果您发布实际帮助函数的样子,我们或许可以对其进行改进。
  • @Schwern 我正在使用一个非常大的测试套件(数百个测试),这个特殊的实用程序模块有超过一千行代码。一些测试已经开始失败,因为我们已经弃用了一些代码,所以我试图快速评估发生了什么问题,而不必重构整个测试设置,这承认可以使用一些工作。这就是为什么我一直在寻找一种方法来获取 Test::More 以提供更多信息,而不必手动编辑每个测试来执行 ok $something or diag Carp::longmess $stuff

标签: perl


【解决方案1】:

我不相信 Test::More 基础设施提供了这样的野兽,但你真的需要堆栈跟踪吗?只要您为测试提供描述性名称,仅报告第 13 行就足够了。

要报告第 13 行而不是第 17 行,只需将以下内容添加到您的 sub:

local $Test::Builder::Level = $Test::Builder::Level + 1;

更长的例子:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;

use Test::Most tests => 3;

ok(1, 'first test');

note "The following includes a failed test, but a stack trace would be more helpful";

helper_sub_with_test();       # Line 13

ok(1, 'third test');

sub helper_sub_with_test {
    local $Test::Builder::Level = $Test::Builder::Level + 1;
    ok(0, sprintf "second test (look at line %d)", __LINE__);     # Line 18
}

【讨论】:

  • 是的,堆栈跟踪确实很有帮助,因为这些实用方法中有多个测试。这不是我的代码,否则我会设计得更好一点。
【解决方案2】:

获得所需内容的快速而肮脏的方法是在 Test::Builder::ok 周围放置一个包装器。这就是 Test::Most 的运作方式。

使用Aspect 可以减少这种破解。

use Carp qw(longmess);
use Test::Most;
use Aspect;

after {
    # For some reason, the return value is not being captured by Aspect
    my $last_test = ($_->self->summary)[-1];
    print longmess if !$last_test;
} call "Test::Builder::ok";

sub foo { ok(0) }

foo();
pass;

done_testing;

【讨论】:

    猜你喜欢
    • 2021-03-15
    • 2011-03-03
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2011-07-27
    • 1970-01-01
    相关资源
    最近更新 更多