If you are like me you want to have your markup (html, rss, google sitemap files, etc.) as valid as possible. To achieve this most of us use the w3c validation service or browser add-ons. Testing all your pages this way is hard and error prone. I can also speak from my own experience that after some time you don't keep an eye on your markup because you simply forget about it. Thanks to Kris Wallsmith the new symfony 1.3 version will ship a new method included in sfTesterResponse called isValid() which will test your response for valid markup.
To use this new method you just need to add the method invocation to the response context of your functional tests:
<?php // INSIDE YOUR FUNCTIONAL TESTFILE // do some request with the functional test object ... with('response')->begin()-> // test your response ... isValid()-> end() ?>
If everything wents well you will see summary like this one on your terminal:

Basically the sfTesterResponse::isValid() tries to load the response via the DOMDocument class and returns 'response is well-formed "xml"'. So for now you just tested that your markup is valid XML code. That's cool for testing RSS or ATOM markup but it would be a lot cooler to validate your markup against the DTD files that you defined in your DOCTYPE when using HTML markup.
If you want to do so it's as simple as turning on the light switch in your living room. Just pass a boolean true to sfTesterResponse::isValid() and your markup get's tested against the defined DTD files:
<?php // INSIDE YOUR FUNCTIONAL TESTFILE // do some request with the functional test object ... with('response')->begin()-> // test your response ... isValid(true)-> end() ?>
If your responses are valid you will see something like the following output.

So, if you pass a boolean true to sfTesterResponse::isValid() your markup get's validated against the defined DTD files. But there is something you need to know about the DTD validation. Since W3C blocks requests that don't come from browsers the symfony developers were forced to manipulate the path of the DTD files to a bundled version of them.
If you have a XSD or Relax NG file available to validate your markup it's easy use to it in your test. If you pass a path as string to sfTesterResponse::isValid() it will this use file to validate your markup against it. This way you can for example test your generated google sitemap files against the XSD file which is shipped by google:
<?php // INSIDE YOUR FUNCTIONAL TESTFILE // do some request with the functional test object ... with('response')->begin()-> // test your response ... isValid(sfConfig::get('sf_test_dir') . '/data/xsd/google/sitemap.xsd')-> end() ?>
I dumped the XSD file in the 'test/data/xsd' folder which I created by hand to have all XSD files for my tests in one place. This time sfTesterResponse::isValid() tries to validate the markup against XSD file you defined via the passed parameter. If everything went well you will see the following output.

Sadly I had no chance to test markup against Relax NG files. But it works the same as with XSD files.
The great thing about testing your pages for valid markup is the fact that you can easier track down validation errors because the output of the tests will give you information about the error. Let's take the dynamically generated google sitemap as example. If have a typo in your code like this one:
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <locd>http://www.example.com</loc> <changefreq>daily</changefreq> <priority>0.8</priority> </url> <!-- More Url's following ... --> </urlset>
Running the test for this page you will get the following output:

You can track down the error easy and fix the typo. However this is a very simple example. Some errors messages may be not as helpful as the last one.
As you can see sfTesterResponse::isValid() gives you as a developer a great new feature in your symfony toolkit. But it's a new features so it needs users to test it and create bug reports if something is wrong with it. So I encourage everybody who is already using the symfony 1.3 branch to test this feature so that the core developers get as much feedback as possible.
This work by Dennis Benkert is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
© 2009 by Dennis Benkert - legal information
Great stuff! Isn't it possible to cheat w3c by changing browser identification? I think I've done this before.
Actually that is not the reason. I wasn't aware that there should be something like you described.
Many tools query the dtds and xsds so why should they be blocked.
The reason for incorporating them was to avoid network traffic.
What if you want to run your tests while in a plane?
or when your build machine is inside your network and has no access to the internet?
you should never depend on online resources, so we provided our own catalog of xsds to validate against.
After testing sfTesterResponse::isValid() the first time I faced the problem that the DTD files couldn't be loaded. Googling brought me to a blog post of W3C which describes what I wrote in my post (Sorry for not referencing it earlier).
http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic
And another good point for a bundled version of the DTD files is the fact that the tests will run much faster because the DTD can be read from the filesystem itself.