sebastianbergmann/comparator · error · ComparisonFailure

Failed asserting that two DOM

Error message

Failed asserting that two DOM %s are equal.

What it means

ComparisonFailure thrown by DOMNodeComparator::assertEquals when the normalized text serialization of two DOM nodes differs. The message says 'two DOM documents' when the expected node is a DOMDocument, otherwise 'two DOM nodes'. Both nodes are converted to text (optionally lower-cased when ignoreCase=true) via nodeToText before comparison.

Solutions

  1. Diff the expectedAsString/actualAsString carried by the exception to see the first textual difference.
  2. Normalize whitespace: build documents without pretty printing or strip insignificant whitespace before comparing.
  3. Pass $ignoreCase=true when only casing of tags/text differs.
  4. Ensure both sides are the same kind of node (document vs element/fragment).
  5. Fix the producer (template/renderer) or the fixture so the serialized markup matches.

Example fix

// before
$c->assertEquals($doc1, $doc2); // fails on attribute order/whitespace casing
// after
$c->assertEquals($doc1, $doc2, 0.0, false, true); // ignoreCase=true when only case differs
Defensive patterns

Strategy: validation

Validate before calling

// normalize before comparing: strip whitespace-only text nodes
$xp = new DOMXPath($doc);
foreach ($xp->query('//text()[normalize-space(.)=""]') as $t) { $t->parentNode->removeChild($t); }

Type guard

function isDomNodeLike(mixed $v): bool { return $v instanceof DOMNode; }

Try / catch

try {
    $c->assertEquals($expectedDoc, $actualDoc);
} catch (ComparisonFailure $e) {
    // compare $e->getExpectedAsString() vs $e->getActualAsString()
}

Prevention

When it happens

Trigger: assertEquals on two DOMDocument/DOMNode objects whose serialized text differs — different elements, attributes, attribute order-sensitive content, whitespace/indentation differences, or casing (when ignoreCase=false).

Common situations: Testing generated HTML/XML output against fixtures; XML produced with different pretty-printing or whitespace than the fixture; missing or differently-ordered attributes; text content casing differences; comparing a fragment with a full document.

Related errors


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

Appendix: source

Thrown at src/DOMNodeComparator.php:51

    }

    /**
     * @param array<mixed> $processed
     *
     * @throws ComparisonFailure
     */
    public function assertEquals(mixed $expected, mixed $actual, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false, array &$processed = []): void
    {
        assert($expected instanceof DOMNode);
        assert($actual instanceof DOMNode);

        $expectedAsString = $this->nodeToText($expected, $ignoreCase);
        $actualAsString   = $this->nodeToText($actual, $ignoreCase);

        if ($expectedAsString !== $actualAsString) {
            $type = $expected instanceof DOMDocument ? 'documents' : 'nodes';

            throw new ComparisonFailure(
                $expected,
                $actual,
                $expectedAsString,
                $actualAsString,
                sprintf("Failed asserting that two DOM %s are equal.\n", $type),
                $this->contextLines(),
            );
        }
    }

    /**
     * Canonicalizes nodes, removes empty text nodes and merges adjacent text nodes,
     * and optionally ignores case.
     *
     * @see https://github.com/sebastianbergmann/phpunit/pull/1236#issuecomment-41765023
     */
    private function nodeToText(DOMNode $node, bool $ignoreCase): string
    {

View on GitHub (pinned to 00837a9d22)