开发者

How to unit test HTML output with PHPUnit?

I'm new to PHPUnit, and I'm having some trouble with unit testing HTML output.

My test follows:

/**
* @covers Scrap::removeTags
*
*/
public function testRemoveTags() {

    // Variables
    $simple_parameter        = 'script';
    $array_parameter         = array('script', 'div');
    $html                    = '<div class="pubanunciomrec" style="background:#FFFFFF;"><script type="text/javascript"><!-- google_ad_slot = "9853257829"; google_ad_width = 300; google_ad_height = 250; //--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div><table></table>';

    // Expected HTML
    $expected_html_whitout_script     = new DOMDocument;
    $expected_html_whitout_script->loadHTML('<div class="pubanunciomrec" style="background:#FFFFFF;"></div><table></table>');
    $expected_html_without_script_div = new DOMDocument;
    $expected_html_without_script_div->loadHTML('<table></table>');

    // Actual HTML
    $actual_whitout_script     = new DOMDocument;
    $actual_whitout_script->loadHTML($this->scrap->removeTags($html, $simple_parameter));
    $actual_without_script_div = new DOMDocument;
    $actual_without_script_div->loadHTML($this->scrap->removeTags($html, $array_parameter));


    // Test
    $this->assertEquals($expected_html_whitout_script, $actual_whitou开发者_高级运维t_script);
    $this->assertEquals($expected_html_without_script_div, $actual_without_script_div);

}

My problem is that the DOMDocument object generates some HTML code and I can't compare it. How can I print the DOMDocument object to see the output? Any clues on how to compare the HTML?

Sorry for my bad english.

Best Regards,


Since 2013, there is another way to test HTML Output using PHPUnit. It is using assertTag() method that can be found in PHPUnit 3.7 and 3.8.

For example :

// Matcher that asserts that there is an element with an id="my_id".
$matcher = array('id' => 'my_id');

// Matcher that asserts that there is a "span" tag.
$matcher = array('tag' => 'span');

// Matcher that asserts that there is a "div", with an "ul" ancestor and a "li"
// parent (with class="enum"), and containing a "span" descendant that contains
// an element with id="my_test" and the text "Hello World".
$matcher = array(
    'tag'      => 'div',
    'ancestor' => array('tag' => 'ul'),
    'parent'   => array(
        'tag'        => 'li',
        'attributes' => array('class' => 'enum')
    ),
    'descendant' => array(
        'tag'   => 'span',
        'child' => array(
            'id'      => 'my_test',
            'content' => 'Hello World'
        )
    )
);

// Use assertTag() to apply a $matcher to a piece of $html.
$this->assertTag($matcher, $html);

Read more in official PHPUnit Website.


You may want to consider looking at Selenium. It is a browser-based testing tool for doing functional tests for a web site.

You write scripts which involve loading a web browser and simulating clicks and other actions, and then doing asserts to check that, for example, specific page elements are present, in the correct place or contain the expected values.

The tests can be written using an IDE that runs as a plug-in for Firefox, but they can be run against all the major browsers.

We have a suite of Selenium tests that run as part of our CI process, allowing us to see very quickly if something has gone wrong with our HTML output.

All in all, its a very powerful testing tool.

Also, it integrates with PHPUnit (and other language-specific tools), so it does answer your question, although probably not in the way you were thinking of.


You should be a bit careful in comparing outputted HTML to a correct template. Your HTML will change a lot, and you can end up spending too much time on maintaining your tests.

See this post for an alternative approach.


You can use saveHtml method of DOMDocument and compare the output.


You can compare two HTML strings with PHPUnit assertXmlStringEqualsXmlString method:

$this->assertXmlStringEqualsXmlString($emailMarkup, $html);

where $emailMarkup - expected HTML string $html - current HTML string

Important! HTML strings must be XML-valid. For example use

<br/>

instead

<br>

Also tag attributes must have values, e.g. use

<hr noshade="true">

instead

<hr noshade>


It is best not to validate against a template (unless you want to make sure nothing changes, but that is a different condition / test that you may want). You will probably want to test that your HTML includes what the user should actually see, and not that the actual HTML that formats the output is exactly what is in a template. I would recommend sending your HTML through a converter that changes it into pure text, then testing to see if you get the right results. This accommodates future functionality and data related changes that are inevitable in software development. You don't want your tests failing because someone added a class somewhere. This is probably a custom type test you will want to code yourself to meet your needs.

It is also best to insure your HTML (and CSS) is correctly formatted, what ever it may be. Sometimes invalid HTML is parsed and displayed somewhat reasonably by the browser, but best not to rely on browsers knowing what do to with invalid HTML and CSS. I have seen many issues fixed just by correcting the HTML.

I developed a library that outputs HTML PHPFUI, and I could not find any recent or even supported HTML unit tests for PHPUnit. So I created https://packagist.org/packages/phpfui/html-unit-tester which is a modern HTML and CSS unit tester. It validates against w3.org standards, so will always be up to date with the latest.

Basically you can pass in HTML fragments, or entire pages, and it will check validity of your HTML. You can test strings, files or even live URLs. Really handy to make sure all the HTML and CSS you are generating is valid. I found so many issues with my code with this library, was definitely worth the time invested. Hope everyone can benefit from it as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜