Test the HTML with DOM parser and PHPUnit
When testing code that returns HTML in PHP, I’ve been doing lazy checks with regular expressions.
But I decided to run test with DOM, because I had been feeling uneasy.
Initially, I tried to use DOMDocument::loadHTML for it. But I got an error when the HTML contains the <section /> like following.
DOMDocument::loadHTML(): Tag section invalid in Entity, line: 1
So, I used following libraries and it looks good to me.
symfony/dom-crawlersymfony/css-selector
Install dependencies
To install those libraries, run composer command like following.
$ composer require symfony/dom-crawler symfony/css-selector --dev
Write a method that returns a DOM
First, prepare a method that returns DOM when passing HTML.
<?php
class Sample_Test extends UnitTestCase
{
private function dom( $html )
{
$dom = new Symfony\Component\DomCrawler\Crawler();
$dom->addHTMLContent( $html, "UTF-8" );
return $dom;
}
}
Write a test
test_html() is the test to check the HTML. It is checking how many nodes that matches the CSS selector.
<?php
class Sample_Test extends UnitTestCase
{
public function test_html()
{
$result = do_something();
$dom = $this->dom( $result );
$this->assertSame( 1, count( $dom->filter( '.col-3' ) ) );
$this->assertSame( 6, count( $dom->filter( 'section.item' ) ) );
}
private function dom( $html )
{
$dom = new Symfony\Component\DomCrawler\Crawler();
$dom->addHTMLContent( $html, "UTF-8" );
return $dom;
}
}
do_something() is a function that returns HTML. I passed CSS selector to `$dom->filter()` and asserted the number of the nodes.
Test whether it is valid HTML
Unfortunately, dom-clawler can’t test whether it is valid HTML.
But, I guess we can check if we forget to close tag or so like following.
private function assertMaybeValidHTML( $html )
{
$html = str_replace( 'section', 'div', $html );
$html = str_replace( 'aside', 'div', $html );
$dom = new DOMDocument();
$dom->loadHTML( '<html><body>' . $html . '</body></html>' );
}
