PHPUnit断言两个数组相同失败,目视无差异如何解决
这种目视完全一致但PHPUnit断言数组不一致的问题,本质是字符串中存在视觉不可见的特殊字符,或者空白字符的编码类型不一致导致的。
第一步:定位具体差异
你可以先通过输出差异字段逐字符的ASCII编码确认差异点,代码示例:
// 取出差异字段的预期和实际值 $expectedStreet = $expected['street']; $actualStreet = $actual['street']; // 打印每个字符的编码 echo "预期值字符编码:\n"; foreach(mb_str_split($expectedStreet) as $c) { echo ord($c).' '; } echo "\n实际值字符编码:\n"; foreach(mb_str_split($actualStreet) as $c) { echo ord($c).' '; }
常见差异场景
- 除了你已经排查的非打断空格(ASCII 160),还可能存在零宽空格(ASCII 8203)、全角空格(ASCII 12288)、换行/制表符残留、字符串开头/结尾隐藏了UTF-8 BOM头
- 两个字符串采用了不同的Unicode编码范式(如NFC/NFD),对于包含特殊符号的内容会出现目视一致但编码不同的情况
通用解决方法
在比对前先对两个数组的字符串字段做归一化处理,示例代码:
function normalizeString(string $input): string { // 移除UTF-8 BOM头 $input = preg_replace('/^\x{EF}\x{BB}\x{BF}/u', '', $input); // 所有类型的空白统一替换为普通半角空格 $input = preg_replace('/\p{Z}+/u', ' ', $input); // Unicode编码范式归一化 $input = normalizer_normalize($input, Normalizer::FORM_C); // 去除首尾空白 return trim($input); } // 对两个数组做归一化处理后再比对 $expectedNormalized = array_map('normalizeString', $expectedArray); $actualNormalized = array_map('normalizeString', $actualArray); $this->assertSame($expectedNormalized, $actualNormalized);
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

