多くのプロジェクトで、テストでXMLデータを比較する必要がありました。
実際、モジュールの結果はXMLデータになります。 その場合、 TDDの原則に従って、それらの生成方法を確認する必要があります。 私は、開発時にそれらに固執するようにします。
私の意見では、コード内でXMLの生成をテストするための最良の方法について話をしようと思います。 XML比較ツールとして、 XmlUnitを使用しました 。
テストでXMLデータを迅速かつ便利に比較する必要があります。 私は車輪を再発明したくなかったので、これらの目的のために最も人気のあるライブラリを選びました。 最初に、解決した問題のリストを説明しようとします。
それがすべて始まった方法
どういうわけか、次のプロジェクトに取り組んでいる間に、同僚のテストを破りました。 テストの勉強を始めたとき、次のようなことがわかりました。
@Test public void testSomeXmlGeneration() { // String result = someModule.generateXML(); // XML File file = File.createTempFile("actial_data", ".xml"); FileWriter fileWriter = new FileWriter(file); fileWriter.write(result); fileWriter.close(); File fileExpect = new File(this.getClass().getResource("/expected_data.xml").getFile()); FileAssert.assertBinaryEquals(fileExpect, file); }
ここで、データが生成され、リソースの元のデータと比較されます。 テストには、 JUnit4が使用されます。 また、理想的には、元のファイルは開発者が手動で作成する必要があることに注意してください。
このコードが悪いのはなぜですか?
ポイントを正当化しようとします。
1. 2つのファイルを比較するにはジェスチャが多すぎます
実際、多くの動きがあり、頻繁に比較する必要がある場合、何らかの形でこのコードが前後にコピーされ、実際に頻繁に発生します。 これに関係するのは時間の不足です。
2.生成されたXMLコードの検証はありません
有効性がチェックされなかったという事実により、別のモジュールは無効なデータの処理を拒否しましたが、テストではすべてが正常でした。 テストをデバッグする段階でこの問題を解決したかったのです。
3.タグまたは属性の順序が異なるため、同一のXML構造とデータは同じではない場合があります。
たとえば、次のように:
オプション1 | タグを並べ替える |
---|---|
|
|
または:
オプション2 | 属性の順序を変更する |
---|---|
|
|
4. XMLフォーマットテストが必要
記事の冒頭に示したテストでは、XMLデータはスペースや改行なしで表示されました。 違いを感じてください:
オプション3 | スペースと改行を削除する |
---|---|
|
|
5.データ内の自動処理された転送
オプション3 | データ内の行を折り返す |
---|---|
|
|
記事の冒頭で検討したテストでは、ソースデータは1行で、タグと属性のみがわずかに大きくなりました。 そこにエラーを置くことは非常に簡単で、テストがパスするように修正するのは長くて苦痛です。
上記のすべての問題は、座標を修正することにしました。
- ライブラリを使用してXMLを比較し、その有効性を確認します。
- このライブラリを使用するようにすべてのテストを書き直します(まだいくつかのテストがあります)。
短い検索の後、私の選択はXmlUnitに落ちました。
基本的なXmlUnit接続メソッド
XmlUnitライブラリは、主にJUnit3の拡張です。
その基盤は、JUnit3のTestCaseクラスの子孫であるXMLTestCaseクラスです。 ここでは、クラスの使用の主な例を見ることができます。
実際には、XmlUnitは他のテストライブラリで簡単に使用できます。 これにはDiffクラスがあります。
さあ行こう
私のプロジェクトでは、mavenを使用します。 XmlUnitをMavenの依存関係として接続します。 これを行うには、pom.xmlを開き、依存関係に新しい依存関係を追加します。
<dependencies> <!-- ….- ... --> <dependency> <groupId>xmlunit</groupId> <artifactId>xmlunit</artifactId> <version>1.3</version> </dependency> </dependencies>
テストを開き、そこに新しい比較を記述します
@Test public void testSomeXmlGeneration() { // String result = someModule.generateXML(); Diff diff = new Diff(getResourceAsString("/expeced_data.xml"), result); assertTrue("XML ", diff.similar()); }
テストを実行します...そして動作しません。 インターネットでもう少し検索した後、解決策を見つけました。 タグ間のスペースの問題でした。 それらを無視するには、プリセットを追加する必要があります。
@Before public void setUp() throws Exception { XMLUnit.setIgnoreComments(true); XMLUnit.setIgnoreWhitespace(true); }
すべてのようで、結果を楽しむことができます。 ただし、XMLでエラーが発生したとします。 次に、どのタグが問題であるかを知る必要があります。
次の例は、解決に役立ちます。
// class TestXmls { @Before public void setUp() throws Exception { XMLUnit.setIgnoreComments(true); XMLUnit.setIgnoreWhitespace(true); } @Test public void testSomeXmlGeneration() { // String result = someModule.generateXML(); Diff diff = new Diff(getResourceAsString("/expeced_data.xml"), result); Tools.showXmlDiff(diff); assertTrue("XML ", diff.similar()); } } // public final class Tools { public static void showXmlDiff(Diff diff) { DetailedDiff detDiff = new DetailedDiff(diff); List differences = detDiff.getAllDifferences(); for (Object object : differences) { Difference difference = (Difference) object; System.out.println("***********************"); System.out.println(difference); System.out.println("***********************"); } } }
showXmlDiffメソッドに注意してください。 その中で、差異のリストを取得して表示します。
他に何ができますか?
- XmlUnitは、比較に加えて、XMLデータの有効性をチェックする機能を提供します。
- XmlUnitを使用して、XSLT変換をテストできます。
- などなど...
文学
情報を得たリンク。
- 公式XmlUnitドキュメント
- 使用例
- XmlUnitマニュアル
- 役立つ答えがたくさんあるStackoverflowの質問
- 人気のあるユーティリティとライブラリの比較リスト
- UPD: その他のXmlUnitの使用例
UPD: Lure_of_Chaosとの議論の後に、別のリンクを参照リストに追加しました。 そこでは、何らかの理由で公式ドキュメントには書かれていないXML検証やその他の美しい機能について読むことができます。
繰り返しになりますが、XmlUnitを使用すると、 DTDおよびXSDスキームに対してXMLの有効性を確認できます。
Lure_of_Chaosが正しく指摘しているように、XSDスキームでは、 要素が 定義される 順序を要求できます。 テストでこれをテストすることは重要です。
UPD2 : 検証 の最後の例を 修正しました 。 ありがとう、 コルウィン 。
それだけです、ご清聴ありがとうございました。