2010/04/14

XML Assertions in MbUnit v3

If you have already made some attempts in the past to write unit tests for testing XML output, then you surely noticed that it is not an easy task. Usually, the initial approach is to test the resulting XML data by using a simple text equality assertion. Unfortunately, it does not work very well; mainly because XML contains insignificant whitespaces, comment tags, or self-closing empty elements. Furthermore, we would like sometimes to ignore case of element names, or to ignore the order of the attributes in the same parent element.

For example, are those two fragments equal?
<value x='123' y='456'/>
<VALUE y='456' x='123'></VALUE>
Well, it depends. The name of elements differs by the case, the attributes are in a different order, and one of element is self-closing while the later is not. Nevertheless, it's perfectly reasonable to consider they are equal. And obviously, a unit test which makes use of a text equality assertion will miserably fail because the actual strings are just different.

Fortunately, MbUnit v3.2 proposes some fresh new assertions to test XML data. Basically, the assertions parse the fragments of XML (expected and actual) and compare the resulting trees by taking in account the equality options specified by the user. This is very easy to use. Let's compare our fancy fragments by using Assert.Xml.AreEqual:
[Test]
public void MyXmlTest()
{
var generator = new MyXmlGenerator();
string actual = generator.ToXml();
Assert.Xml.AreEqual("<value x='123' y='456'/>", actual, XmlOptions.Loose);
}
Remark the loose equality options which tells the assertions to ignore comment tags, case of names/values, order of attributes, etc.

More details and examples may be found the Gallio Wiki.

3 comments:

Jeff Brown said...

You should show off the formatting!

hfrmobile said...

Why not checking against XSD?

Yann Trevin said...

@hfrmobile. Validating against XSD is indeed a solution. But in many scenarios, XSD is not available beforehand (eg. testing the output of a custom extension method for the ASP.NET MVC HtmlHelper) Therefore it is easier to compare the output XML with just the expected fragment. The assertions also provide friendly messages indicating which elements or attributes are failing with colorful diffs and paths.