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

Perl中Test::Builder子测试使用is_deeply报错的解决求助

在Perl 5.18.2的Test::Builder子测试中使用is_deeply的正确方法

问题背景

我正尝试将代码从use Test::More迁移到use Test::Builder,在Perl 5.18.2环境下调用is_deeply时遭遇报错:

Cannot run test (h_c: is_deeply($n, $s)) with active children at /usr/lib/perl5/5.18.2/Test/More.pm line 1020

由于Test::Builder本身没有is_deeply方法,我通过use Test::More 'import' => [qw(is_deeply)]仅导入该方法,但在子测试($tb->child())中调用时程序崩溃。

调试后发现,is_deeply内部创建的Test::Builder实例并非当前子测试的实例,而是全局实例——该实例存在未结束的一级子测试,导致Test::Builder::ok中的检测失败。我已复现问题的最小示例,还发现使用Test::Builder->new而非create会触发问题,临时通过local $Test::Builder::Test = $TB可解决但存在风险,请问是否有在子测试中使用is_deeply的正确方法?


解决方案

方法1:用Test::Builder::Module封装测试函数

创建自定义测试模块继承Test::Builder::Module,它会自动将导入的测试函数绑定到当前活跃的Test::Builder实例,避免全局实例冲突:

package MyTest;
use base 'Test::Builder::Module';
use Test::More 'import' => [qw(is_deeply)];
1;

测试脚本中使用:

use Test::Builder;
use MyTest;

my $tb = Test::Builder->create;
$tb->plan(tests => 1);

my $child = $tb->child('子测试');
$child->plan(tests => 1);
is_deeply([1,2,3], [1,2,3], '深层结构对比');
$child->finalize;

$tb->finalize;

方法2:调用is_deeply时指定子测试实例

Perl 5.18.2版本的Test::More中,is_deeply支持通过builder参数指定使用的Test::Builder实例,直接在调用时传入子测试对象即可:

use Test::Builder;
use Test::More 'import' => [qw(is_deeply)];

my $tb = Test::Builder->create;
$tb->plan(tests => 1);

my $child = $tb->child('子测试');
$child->plan(tests => 1);
is_deeply([1,2,3], [1,2,3], '深层结构对比', { builder => $child });
$child->finalize;

$tb->finalize;

方法3:改用Test::More的subtest函数

如果项目允许,推荐直接使用Test::More原生的subtest创建子测试,所有测试函数会自动关联正确的实例,无需手动管理Test::Builder对象:

use Test::More tests => 1;

subtest '子测试' => sub {
    plan tests => 1;
    is_deeply([1,2,3], [1,2,3], '深层结构对比');
};

临时方案的风险说明

你提到的local $Test::Builder::Test = $TB虽然能临时解决问题,但会全局替换当前活跃的Test::Builder实例,若测试中存在嵌套子测试或并发逻辑,可能导致测试计数错误、结果混乱等问题,不建议在正式测试代码中使用。

内容的提问来源于stack exchange,提问作者U. Windl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:48:37