web-dev-qa-db-ja.com

XML生成のユニットテスト

Xmlをテストするために人々が推奨する単体テスト戦略は正しく生成されています。

私の現在のテストは、次のような原始的なもののようです。

[Test]
public void pseudo_test()
{
   XmlDocument myDOC = new XmlDocument();
   mydoc = _task.MyMethodToMakeXMLDoc();

   Assert.AreEqual(myDoc.OuterXML(),"big string of XML")
}
34
Dan

まず、ほとんどの人が言っているように、XMLにスキーマが定義されている場合は、XMLを検証します。 (ない場合は、定義します。)

ただし、ドキュメントに対してXPathクエリを実行することで、テストよりもはるかに詳細なテストを作成できます。例:

string xml="Your xml string here" ;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
path = "/doc/element1[@id='key1']/element2[. = 'value2']";
Assert.IsTrue(doc.SelectSingleNode(path) != null);

これにより、ドキュメントがセマンティック的に有効であるかどうかだけでなく、ドキュメントを生成するメソッドが期待する値をドキュメントに入力しているかどうかをテストできます。

21
Robert Rossney

XMLUnit が役立つ場合があります。

12
Ionuț G. Stan

Fluent Assertions は、流暢で読みやすいスタイルでテストアサーションを表現するための優れたライブラリです。これは、すべての主要なユニットテストフレームワークで機能します。

また、いくつかの便利なXML機能(すべて例から抜粋 ここ )があります。例:

xElementA.Should().Be(xElementB);

xDocument.Should().HaveRoot("configuration");
xDocument.Should().HaveElement("settings");

xElement.Should().HaveAttribute("age", "36");
xElement.Should().HaveElement("address");

xAttribute.Should().HaveValue("Amsterdam");

これは、元の質問で指定されたXmlDocumentオブジェクトではなくLINQ-To-XMLで機能することに注意してください。しかし、個人的には、最近、最初の選択肢としてLINQ-To-XMLを使用していることがわかりました。

また、ニーズに合わせてXMLアサーションをさらに追加したい場合は、非常に簡単に拡張できます。

6
Holf

もう1つの可能性は、XmlReaderを使用して、エラー数が0より大きいかどうかを確認することです。次のようなものです。

    void CheckXml()
    {
        string _xmlFile = "this.xml";
        string _xsdFile = "schema.xsd"; 
        StringCollection _xmlErrors = new StringCollection();

        XmlReader reader = null;
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationEventHandler += new ValidationEventHandler(this.ValidationEventHandler);
        settings.ValidationType = ValidationType.Schema;
        settings.IgnoreComments = chkIgnoreComments.Checked;
        settings.IgnoreProcessingInstructions = chkIgnoreProcessingInstructions.Checked;
        settings.IgnoreWhitespace = chkIgnoreWhiteSpace.Checked;
        settings.Schemas.Add(null, XmlReader.Create(_xsdFile));
        reader = XmlReader.Create(_xmlFile, settings);
        while (reader.Read())
        {
        }
        reader.Close();
        Assert.AreEqual(_xmlErrors.Count,0);
    }    

    void ValidationEventHandler(object sender, ValidationEventArgs args)
    {
        _xmlErrors.Add("<" + args.Severity + "> " + args.Message);
    }
5
Mike K.

XMLスキーマまたはDTDに対して検証し、ノードが期待する値を持っていることも確認してください。

4
svinto

出力が期待される標準形式がある場合は、XMLスキーマまたはDTDを作成し、それに対して検証してみませんか。これはデータに依存しないため、柔軟性があります。また、XMLの形成方法を定義することは、システムを設計するときに役立ちます。

3
Jeremy French

このブログ投稿 by marianorは、XElement構造を比較するための軽量な方法を提供するので、取り組む前にそれを試してみます XMLUnit

最初に行うことは、2つのXMLを正規化することです... Linqを使用して...両方の要素が正規化された後、単に両方の文字列を比較できます。

XMLは、要素名と属性名をソートすることによって正規化されます。

1
Don Kirkby

一部の商用xmlパーサーが正しいと想定し、それに対してxmlコードを検証してみませんか?何かのようなもの。

Assert.IsTrue(myDoc.Xml.ParseOK)

それ以外で、徹底したい場合は、自分でパーサーを作成し、xml仕様で必要な各ルールを検証する必要があると思います。

0
Vitor Silva

スキーマを使用して検証するもう1つの理由は、XMLノードは明示的に順序付けられていますが、XML属性は順序付けられていないためです。

したがって、次の文字列の比較:

Assert.AreEqual(myDoc.OuterXML(),"big string of XML")

xMLの1つのビットが手動で作成され、他のビットがプログラムで作成された場合に簡単に発生する可能性があるように、属性の順序が異なると失敗します。

0
merlinc

XmlSchemaクラスを使用して、XSDスキーマに対して検証します。 System.XMLの下にあると思います。もう1つのオプションは、XMLをオブジェクトに逆シリアル化するシリアル化クラス(XMLSerializer)を作成することです。利点は、構造を暗黙的に検証し、その後、結果のオブジェクトを使用してテストするために値に簡単にアクセスできることです。

0
Adrian Zanescu

DTDを使用して、生成されたxmlの有効性を確認できます。

正しいコンテンツをテストするには、 XMLUnit を選択します。

XMLUnitを使用したxmlのアサート:

XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);

Diff diff = new Diff(expectedDocument, obtainedDocument);
XMLAssert.assertXMLIdentical("xml invalid", diff, true);

あなたが遭遇するかもしれない一つのことは、生成されたxmlが変化する識別子(id/uid属性など)を含むかもしれないという事実です。これは、生成されたxmlをアサートするときに DifferenceListener を使用することで解決できます。

このようなDifferenceListenerの実装例:

public class IgnoreVariableAttributesDifferenceListener implements DifferenceListener {

    private final List<String> IGNORE_ATTRS;
    private final boolean ignoreAttributeOrder;

    public IgnoreVariableAttributesDifferenceListener(List<String> attributesToIgnore, boolean ignoreAttributeOrder) {
        this.IGNORE_ATTRS = attributesToIgnore;
        this.ignoreAttributeOrder = ignoreAttributeOrder;
    }

    @Override
    public int differenceFound(Difference difference) {
        // for attribute value differences, check for ignored attributes
        if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID) {
            if (IGNORE_ATTRS.contains(difference.getControlNodeDetail().getNode().getNodeName())) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
        }
        // attribute order mismatch (optionally ignored)
        else if (difference.getId() == DifferenceConstants.ATTR_SEQUENCE_ID && ignoreAttributeOrder) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }
        // attribute missing / not expected
        else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) {
            if (IGNORE_ATTRS.contains(difference.getTestNodeDetail().getValue())) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
        }

        return RETURN_ACCEPT_DIFFERENCE;
    }

    @Override
    public void skippedComparison(Node control, Node test) {
        // nothing to do
    }
}

differenceListenerの使用:

    XMLUnit.setIgnoreWhitespace(true);
    XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);

    Diff diff = new Diff(expectedDocument, obtainedDocument);
    diff.overrideDifferenceListener(new IgnoreVariableAttributesDifferenceListener(Arrays.asList("id", "uid"), true));

    XMLAssert.assertXMLIdentical("xml invalid", diff, true);
0
R. Oosterholt

結果のドキュメントが整形式であることを確認します結果のドキュメントが有効であることを確認します結果のドキュメントが正しいことを確認します。

おそらく、有用なデータからXMLドキュメントを作成しているので、テストの入力を適切にカバーしていることを確認する必要があります。私が見る最も一般的な問題は

  • 誤ってエスケープされた要素
  • 誤ってエスケープされた属性
  • 誤ってエスケープされた要素名
  • 誤ってエスケープされた属性名

したがって、まだ行っていない場合は、XML仕様を確認して、各場所で何が許可されているかを確認する必要があります。

各テストでどの程度の「チェック」が行われるべきかは、すぐにはわかりません。それはあなたの問題空間にあるユニットが何であるかに大きく依存すると思います。各単体テストが、1つのデータがXMLで正しく表現されていることを確認していることは合理的と思われます。この場合、単一のXPathの場所で適切なデータを見つけるという簡単なチェックが最善であるというRobertに同意します。

ドキュメント全体をチェックしたい大規模な自動テストの場合、効果的であることがわかったのは、ドキュメントでもある期待される結果を取得し、XPath式を使用してノードごとに対応するノードを見つけることです。実際のドキュメントで、2つのノードでエンコードされたデータの正しい比較を適用します。

このアプローチでは、通常、最初の障害で中止するのではなく、すべての障害を一度にキャッチする必要があるため、不一致が発生した場所を追跡する方法について注意が必要な場合があります。

もう少し作業を行うことで、特定の要素タイプをテストから免除されているものとして認識したり(タイムスタンプなど)、それらが同等のノードへのポインターであることを検証したり、その他のカスタム検証を行うことができます。

0
VoiceOfUnreason

この新しい 承認テスト ライブラリを使用してXMLテストを支援する予定です。

仕事にぴったりのようですが、使った経験がないのでまずは自分で読んでください。

0
tpower