Click here to Skip to main content
15,867,594 members
Articles / DevOps / Testing

XPath assertions in unit tests

Rate me:
Please Sign up or sign in to vote.
3.67/5 (2 votes)
24 Mar 2014CPOL1 min read 17.7K   75   6   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:

C#
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:

C#
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:

C#
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:

C#
// 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) AutoAppdate.com
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
BugZip archive is not valid Pin
Clark Wilson24-Mar-14 6:04
professionalClark Wilson24-Mar-14 6:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.