sebastianbergmann/comparator · error · ComparisonFailure

Failed asserting that two arrays are equal.

Error message

Failed asserting that two arrays are equal.

What it means

ComparisonFailure thrown by ArrayComparator::assertEquals when two arrays do not contain the same key-value pairs: a key exists in only one array, or a value at a shared key differs (recursively via child comparators). The exception carries exported expected/actual array strings for diffing. This is the standard assertion-failure signal of sebastian/comparator, normally surfaced by PHPUnit assertions like assertEquals.

Solutions

  1. Read the exported 'Array (...)' strings in the exception (expected vs actual) to find the first differing or missing key.
  2. Fix the actual data or the expected fixture so key sets and values match.
  3. For order-insensitive list comparison, pass $canonicalize=true so list elements are sorted before comparison.
  4. For float/datetime elements, pass an appropriate $delta or normalize values (rounding, casing) before comparing.
  5. Use assertArraySubset-style or targeted key assertions to narrow which key mismatches when arrays are large.

Example fix

// before
$factory->getComparatorFor($expected, $actual)->assertEquals($expected, $actual); // throws on order/extra keys
// after
$factory->getComparatorFor($expected, $actual)->assertEquals($expected, $actual, 0.0, true); // canonicalize: sort lists & keys
Defensive patterns

Strategy: try-catch

Validate before calling

// before comparing
if (!is_array($expected) || !is_array($actual)) return;
$missing = array_diff_key($expected, $actual);
$extra = array_diff_key($actual, $expected);
if ($missing || $extra) { /* reconcile key sets first */ }

Try / catch

try {
    $factory->getComparatorFor($expected, $actual)->assertEquals($expected, $actual, 0.0, true);
} catch (ComparisonFailure $e) {
    // inspect $e->getExpectedAsString() / $e->getActualAsString() for the diff
}

Prevention

When it happens

Trigger: Calling Factory::getComparatorFor(...)->assertEquals($expectedArray, $actualArray) (or PHPUnit assertEquals with two arrays) when: a key exists in $expected but not $actual, a key exists in $actual but not $expected, or a nested value fails its own comparator check. Nested failures indent the child ComparisonFailure output.

Common situations: PHPUnit assertion failures in tests comparing fixtures vs. actual data; API response arrays missing/containing extra keys; ordering differences in lists when canonicalize=false; float precision or case differences inside nested arrays; config arrays drifting from expected defaults.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of sebastianbergmann/comparator@00837a9d22 (2026-09-15). Data as JSON: /api/errors/ec1c09cf573b9e7b. Report an issue: GitHub.

Appendix: source

Thrown at src/ArrayComparator.php:177

                    "    %s\n",
                    $exporter->shortenedExport($value),
                );
            } else {
                $actualAsString .= sprintf(
                    "    %s => %s\n",
                    $exporter->export($key),
                    $exporter->shortenedExport($value),
                );
            }

            $equal = false;
        }

        $expectedAsString .= ')';
        $actualAsString .= ')';

        if (!$equal) {
            throw new ComparisonFailure(
                $expected,
                $actual,
                $expectedAsString,
                $actualAsString,
                'Failed asserting that two arrays are equal.',
                $this->contextLines(),
            );
        }
    }

    private function indent(string $lines): string
    {
        return trim(str_replace("\n", "\n    ", $lines));
    }

    private function compare(mixed $a, mixed $b): int
    {
        $typeOrderA = $this->typeOrder($a);

View on GitHub (pinned to 00837a9d22)