Test::More测试中字符串看似相等却失败的原因排查
Perl Test::More单元测试字符串匹配失败排查
我用Perl 5.16和最新版Test::More编写了如下单元测试代码:
is($ret, "ssh: connect to host 1.2.3.187 port 22: Network is unreachable Couldn't read packet: Connection reset by peer ", "putFileWithSFTP bad server ret test");
运行测试后失败,结果如下:
# Failed test 'putFileWithSFTP bad server ret test' # at t/Backup.t line 891. # got: 'ssh: connect to host 1.2.3.187 port 22: Network is unreachable # Couldn't read packet: Connection reset by peer # ' # expected: 'ssh: connect to host 1.2.3.187 port 22: Network is unreachable # Couldn't read packet: Connection reset by peer # '
明明实际返回的字符串和预期字符串看起来完全一致,但测试却未通过,可能的原因有这些:
- 换行符格式不匹配:不同操作系统的换行符标准不一样,Unix/Linux用
\n(LF),Windows用\r\n(CRLF)。你代码里的预期字符串用的是编写环境的换行符,但实际运行时程序返回的字符串可能用了另一种换行格式。Test::More的is是严格字节匹配,哪怕是看不见的换行符差异也会导致测试失败。 - 末尾空白字符差异:表面看末尾都是换行,但实际返回的字符串可能多了一个换行、空格或者制表符,这些空白字符在打印时很难分辨,但会让两个字符串的长度或内容不一致。
- 编码不一致:两个字符串的字符编码可能不同,比如预期字符串是UTF-8编码,而实际返回的是Latin-1编码。虽然显示出来的字符一样,但底层存储的字节值不同,严格匹配自然会失败。
- 隐藏控制字符:字符串中可能包含退格符、NULL字符这类不可见的控制字符,这些字符不会在终端显示,但会改变字符串的实际内容,导致匹配失败。
快速排查方法
可以用Data::Dumper打印两个字符串的原始结构,把所有隐藏字符都显示出来:
use Data::Dumper; $Data::Dumper::Useqq = 1; # 让非打印字符显示为转义序列 print "实际返回的字符串结构:\n", Dumper($ret); print "预期的字符串结构:\n", Dumper("ssh: connect to host 1.2.3.187 port 22: Network is unreachable\nCouldn't read packet: Connection reset by peer\n");
对比输出的转义序列,就能直接找到两个字符串的差异点。
内容的提问来源于stack exchange,提问作者noah
相关产品推荐
相关产品推荐

