Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

XPath assertions in unit tests

0.00/5 (No votes)
24 Mar 2014 1  
Extending Visual Studio unit testing assertions

Introduction

XPath assertions allow you to unit-test code that returns or emits XML. This is useful anywhere from web applications to XML generating code.

Background

XPath is a XML-query standard. You use XPath to retrieve XML nodes - elements or attributes. You can think of XPath as a SQL query with a limited feature-set. XPath syntax is well documents here.

.NET supports XPath version 1.0 queries through it's System.Xml.Xpath namespace.

In this article I'm presenting a class that encapsulates XPath assertions for MS .NET unit-testing framework. It can easily be converted to use other unit-testing frameworks.

I've used unit-testing extensively when writing a client-server application where both ends communicate XML documents. The presented code allowed me to test each side separately and has saved me much work. I hope you'll find it useful!

Using the code

XpathAssert class exposes static methods which you call to assert the XPath expressions. The method in the heart of this class which all other methods use retrieves an iterator over the result set of an XPath expression:

private static XPathNodeIterator GetIterator(XmlDocument xDoc, string xpath)
{
    XPathNavigator xNav = xDoc.CreateNavigator();
    XPathNodeIterator xItr = xNav.Select(xpath);

    return xItr;
} 

The other methods are merely wrappers around this method. For example this method will fail if the XPath query yields an unexpected node count:

public static XPathNodeIterator NodeCountEquals(XmlDocument xDoc, string xpath, int expectedCount)
{
    XPathNodeIterator xItr = GetIterator(xDoc, xpath);
    Assert.AreEqual(expectedCount, xItr.Count,
        string.Format("Xpath expression '{0}' was expected to return {1} results", xpath, expectedCount));

    return xItr;
} 

The following method will fail if the XPath query yields results with unexpected child elements:

public static void LegitimateChildren(XmlDocument xDoc, string elemKidsXpath, params string[] legitimateChildren)
{
    Assert.IsNotNull(legitimateChildren);

    string allowedKids = string.Format("[name()!='{0}'", legitimateChildren[0]);
    for (int i = 1; i < legitimateChildren.Length; ++i)
    {
        allowedKids += string.Format("and name()!='{0}'", legitimateChildren[i]);
    }

    string xpath = elemKidsXpath + allowedKids + "]";

    NodeCountEquals(xDoc, xpath, 0);
} 

As you see this method modifies the query to count child-elements with unexpected names. The assertion tests if the result count is 0.

Now lets look at some XPath assertions:

// Test XML node count
XpathAssert.NodeCountEquals(xmlDoc, "//updatecheck/urls/url", expectedUrlList.Count); 

// Allow specific child node names 
XpathAssert.LegitimateChildren(xmlDoc, "/response/*", "daystart", "app");

// XPath expressions yield equal node count
XpathAssert.NodeCountEqual(xmlDoc, "//ping", "//app/ping");

// Expect a minimal node count
XpathAssert.NodeCountMin(xmlDoc, "//urls[count(/*)=0]", 0); 
 

Points of Interest

This class is one of several I've implemented to extend MS standard unit-testing framework. In subsequent articles I'll provide more classes.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here