You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Perl的Test::More中忽略Test::Differences的TAP测试结果计数

解决Test::Differences的eq_or_diff不计入测试计划的问题

你的核心需求是用eq_or_diff输出美观的差异用于调试,但不想让它占用Test::More的测试计划名额——这完全可以通过Test::Differences自带的非断言函数来实现,不需要hack测试计数。

最佳方案:使用eq_or_diff_text生成差异并通过diag输出

Test::Differences提供了eq_or_diff_text(以及对应的eq_or_diff_data)函数,它们只会生成格式化的差异字符串,不会触发任何测试断言,也就不会向TAP会话中添加测试用例。你只需要把生成的差异字符串通过Test::More的diag函数输出即可,这样既保留了eq_or_diff的美观格式,又完全不影响测试计划。

修改你的最小示例代码如下:

use strict; use warnings; use utf8::all; use open ':std', ':encoding(UTF-8)';
use Test::Differences qw(eq_or_diff_text); # 导入eq_or_diff_text
use Test::Deep::NoTest qw(cmp_details deep_diag);
use Test::More tests => 2;
use JSON;

my $context = 1;
my $extracted_ref = { a => '1', b => '2', c => '3', d => '4', };
my $reference_ref = { a => '1', b => '3', c => '3', d => '4', };

my ($is_compare_ok, $stack) = cmp_details($extracted_ref,$reference_ref);
my $json_reference = JSON->new->canonical->encode($reference_ref);
my $json_extracted = JSON->new->canonical->encode($extracted_ref);

ok(1);
if ($is_compare_ok){
    ok(1);
    return 1;
}else{
    ok(0);
    # 生成差异文本并诊断输出,不会增加测试计数
    my $diff_output = eq_or_diff_text(
        $reference_ref, 
        $extracted_ref, 
        "Error in '$0'", 
        {context=>$context}
    );
    diag($diff_output);
    return 0;
}

对应到你的库文件lib.pm,修改后的代码应该是:

use Test::Differences qw(eq_or_diff_text);
use Test::More qw(diag);

sub some_function_in_other_file_or_library{
    # ... 你的逻辑代码 ...
    my ($is_compare_ok, $stack) = cmp_details($actual, $expected);
    if (!$is_compare_ok) {
        my $diff = eq_or_diff_text($expected, $actual, "Mismatch found", {context => 1});
        diag($diff);
    }
    return $is_compare_ok;
}

这样主脚本的测试计划(2个测试)完全不受影响,只有当差异出现时,才会输出美观的调试信息,且这些信息不会被当作测试用例计数。

其他可选方案(不推荐)

如果你坚持要使用eq_or_diff本身,可以通过临时修改Test::Builder的状态来“抵消”测试计数,但这种方法属于hack,可能在不同Test::Builder版本中出现兼容性问题,且会导致TAP输出出现多余的测试行,不建议在生产代码中使用:

use Test::Builder;

# 在调用eq_or_diff前保存当前测试计数
my $tb = Test::Builder->new;
my $original_test_count = $tb->current_test;

# 调用eq_or_diff,此时会增加测试计数
eq_or_diff($reference_ref, $extracted_ref, "Error in '$0'", {context=>$context});

# 把测试计数改回原来的数值
$tb->current_test($original_test_count);

内容的提问来源于stack exchange,提问作者nck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:42:45