"Seegrid will be due for a migration to confluence on the 1st of August. Any update on or after the 1st of August will NOT be migrated"

Testing Instance Documents

Contents

Related pages



Typical Problems

Validating Links

Within an instance document that validates, I have xlink:href attributes with an incorrect identifier, pointing to an object of the wrong type (an easy mistake when hand-converting samples).

Conclusion

For now, I will go the Python route using the standard unittest built into Python and as much XPath declarative style as possible.

This seems to carry the least baggage and be easiest for non-programmers to read and possibly extend.

Possible Solutions

Python-based testing

Write some Python code which uses XPath expressions as much as possible to give a declarative flavour to the testing code but is still free to use loops and other pattern matching when that is clearer:
  • embedded in the standard unittest framework included in Python builds
  • just in a standalone Python script

py.test has been raved about as More Pythonic but also criticized

A Proper "XML Unit Test environment"

SUT

SUT is implemented in Java and has two parts.

The first is a namespace and vocabulary for embedding test cases into sample XML documents, designed to highlight what is legal and what is not legal in the vocabulary defined in the schema under test. This aspect is independent of what schema language is used and can in theory be applied to any schema language with automatic validation tools.

The second part is a Java implementation using JUnit for testing a W3C Schema with embedded Schematron schema. This implementation reads SUT test suite descriptions written in XML with embedded test cases as described above and then creates a JUnit test suite that can be executed inside JUnit in the usual way.

  <sut:case test="with" result="pass" desc="comment is valid as a root node">
    <comment>What a stange purchase order</comment>
  </sut:case>

Or see a more detailed example:
<purchaseOrder orderDate="1999-10-20">
    <shipTo>
        <name>TestName</name>
        <street>TestStreet</street>
        <city>TestCity</city>
        <state>TestState</state>
        <zip>1</zip>
    </shipTo>
    <billTo>
        <name>TestName</name>
        <street>TestStreet</street>
        <city>TestCity</city>
        <state>TestState</state>
        <zip>1</zip>
    </billTo>
    <items>
        <test:case test="with" result="pass" desc="items element can be empty">
            <test:case test="with" result="pass" desc="items entry can contain an item">
                <item partNum="123-AB">
                    <test:attribute name="partNum" result="fail" desc="item must have a partNum attribute"/>
                    <test:attribute name="partNum" value="12A-AB" result="fail" desc="item must have a well formed partNum attribute"/>
                    <test:case test="without" result="fail" desc="item must have a productName">
                        <productName>TestProductName</productName>
                    </test:case>
                    <test:case id="quantity" test="without" result="fail" desc="item must have a quantity">
                        <quantity>1</quantity>
                    </test:case>
...

XMLUnit

XMLUnit is also implemented in Java

It may not have been updated since 2003.

It focusses on the requirement to compare the XML documents and would be useful if you were writing JUnit tests but can be very very wordy!

public void testCustomNodeTester() throws Exception {
    String testXML = "<fibonacci><val>1</val><val>2</val><val>3</val>"
    + "<val>5</val><val>9</val></fibonacci>";
    NodeTest nodeTest = new NodeTest(testXML);
    assertNodeTestPasses(nodeTest, new FibonacciNodeTester(),
    new short[] {Node.TEXT_NODE, Node.ELEMENT_NODE}, true);
}

private class FibonacciNodeTester extends AbstractNodeTester {
    private int nextVal = 1, lastVal = 1, priorVal = 0;

    public void testText(Text text) throws NodeTestException {
        int val = Integer.parseInt(text.getData());
        if (nextVal != val) {
            throw new NodeTestException("Incorrect value", text);
        }
        nextVal = val + lastVal;
        priorVal = lastVal;
        lastVal = val;
    }

    public void testElement(Element element)
    throws NodeTestException {
        String name = element.getLocalName();
        if ("fibonacci".equals(name) || "val".equals(name)) {
            return;
        }
        throw new NodeTestException("Unexpected element", element);
    }

    public void noMoreNodes(NodeTest nodeTest)
    throws NodeTestException {
    }
}

External Links

-- AndyDent - 02 May 2006

 
Topic revision: r4 - 15 Oct 2010, UnknownUser
 

Current license: All material on this collaboration platform is licensed under a Creative Commons Attribution 3.0 Australia Licence (CC BY 3.0).