XMLUnit

1月 1, 2003 · Posted in XMLUnit · Comment 

XMLUnitとは

XMLUnitはJUnitを拡張して作られたXMLテスティングフレームワーク。JUnitの機能に加えてvalidateや骨組み比較など、XMLに特化したテストがサポートされている。
枠組みの検証、完全一致・類似一致の検証、XSLT変換の検証などに加え、タグの整形がきちんとしていないHTMLに対してもテストを実行することが可能。

入手〜設定

http://xmlunit.sourceforge.net/より、バイナリファイルを入手する。別途、JUnitのバイナリファイルも必要。

Quick Start

http://xmlunit.sourceforge.net/にドキュメントとサンプルコードがあるので、すぐにテストを実行してみることができる。おそらくこのサイトのドキュメントよりソースコードを読んだほうが早い。

様々な設定

特定のXMLパーサや変換エンジンを利用することができる。System.setPropertyまたは、XMLUnitクラスのstaticメソッドを利用する。

System.setPropertyの場合。

System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
                   "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory",
                   "org.apache.xerces.jaxp.SAXParserFactoryImpl");
System.setProperty("javax.xml.transform.TransformerFactory",
                   "org.apache.xalan.processor.TransformerFactoryImpl");

※公式ドキュメントより転載。

XMLUnitクラスのstaticメソッドを利用する場合。

XMLUnit.setControlParser("org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
XMLUnit.setTestParser("org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
XMLUnit.setSAXParserFactory("org.apache.xerces.jaxp.SAXParserFactoryImpl");
XMLUnit.setTransformerFactory("org.apache.xalan.processor.TransformerFactoryImpl");

※公式ドキュメントより転載。

テストの初期化、後始末

JUnitと同じ。setUp()メソッドとtearDown()メソッドを利用する。

テスト実行前の初期化処理

public void setUp() throws Exception{
    super.setUp();
    // コード
}

テスト実行後の後始末

public void tearDown() throws Exception{
    super.tearDown();
    // コード
}

前提・用語

コントロールXML

期待される結果を記述したXML

テストXML

テスト対象のXML

比較:類似(similar)

要素の出現順序は一致していないが、内容は一致している。

比較:一致(identical)

内容が完全に一致している。

類似と一致の例

1:  <root><id>1</id><name>a</name></root>
2:  <root><name>a</name><id>1</id></root>
3:  <root><name>a</name><id>1</id></root>

類似比較:1,2,3のどれを比較しても結果は真となる。
一致比較:2,3を比較した場合に結果が真となるが、それ以外は結果が偽になる。

テストコードの記述

テストメソッドはtestというプレフィックスをつけたメソッド名にする。
例:public void testResult() throws Exception

等価・非等価比較

// 等価比較
public void testEquals() throws Exception{
    String controlXML = "<root><id>001</id><name>ABC</name></root>";
    String testXML = "<root><id>001</id><name>ABC</name></root>";

    assertXMLEqual(controlXML, testXML);
}

// 非等価比較
public void testNotEquals() throws Exception{
    String controlXML = "<root><id>001</id><name>ABC</name></root>";
    String testXML = "<root><id>002</id><name>ABC</name></root>";

    assertXMLNotEqual(controlXML, testXML);
}

類似と一致

類似比較と一致比較。

public void testIdentical() throws Exception {
    String controlXML = "<struct><int>3</int><boolean>false</boolean></struct>";
    String testXML = "<struct><boolean>false</boolean><int>3</int></struct>";
    Diff diff = new Diff(controlXML, testXML);

    assertTrue(diff.similar());
    assertTrue(diff.identical());
}

コントロールXMLとテストXMLを指定して、Diffクラスの初期化を行う。similar()メソッドで類似比較の結果を取得することができ、identical()メソッドで一致比較の結果を取得することができる。

XMLの骨組みを比較

骨組みのみを検査して値の検査を実行しない場合は、IgnoreTextAndAttributeValuesDifferenceListenerクラスを利用する。

public void testCompareToSkeletonXML() throws Exception {
    String controlXML = "<root><id>000</id><name>XXX</name></root>";
    String testXML = "<root><id>2</id><name>john gren</name></root>";
    DifferenceListener differenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
    Diff diff = new Diff(controlXML, testXML);
    diff.overrideDifferenceListener(differenceListener);

    assertTrue(diff.similar());
}

出現順序がバラバラの内容を比較。

どのような出現順序でも内容のみを比較したい場合、ElementNameAndTextQualifierクラスを利用する。

public void testRepeatedChildElements() throws Exception {
    String myControlXML = "<root><num>1</num><num>2</num></root>";
    String myTestXML = "<root><num>2</num><num>1</num></root>";
    Diff diff = new Diff(myControlXML, myTestXML);
    diff.overrideElementQualifier(new ElementNameAndTextQualifier());

    assertXMLEqual(diff, true);
}

XPathで指定した要素・属性の比較

public void testXPaths() throws Exception {
    String controlXml = "<root><name id=\"001\">xxx</name></root>";
    String testXml = "<root><name id=\"001\">xxx</name></root>";

    assertXpathsEqual("//name", testXml, "//name", controlXml);
    assertXpathsEqual("//name/@id", testXml, "//name/@id", controlXml);
}

ノードのカウントを比較

public void testNodeCount() throws Exception {
    String testXML = "<root><n>1</n><n>2</n><n>3</n><n>4</n><n>5</n></root>";
    CountingNodeTester countingNodeTester = new CountingNodeTester(5);

    assertNodeTestPasses(testXML, countingNodeTester, Node.TEXT_NODE);
}