6

XML ファイルを使用し、入力に基づいてテキスト出力を生成するクラスがあります。入力と出力の両方がかなり複雑で、出力には入力にないものが含まれる場合もあります。たとえば、タイムスタンプや、入力によって制御されないライブ データの結果が含まれます。つまり、クラスは純粋な入出力ではありません。変身。

JUnit を使用して結果のテキスト出力をテストしたいと思います。生成されたテキストは入力に基づいてさまざまな方法で変化する可能性があるため、各テストで出力の特定の部分をある種のテンプレートと照合できるようにしたいと考えています。各テンプレートでは、いくつかの単純なテキストの置換と、一致してはならないテキストの範囲も許可する必要があります。

問題は、そのようなフレームワークがすでに存在するかどうかです。

非常に低レベルの可能性の 1 つは、テキストを一致させるためにいくつかの派手な正規表現を使用することですが、正規表現には十分なコンテキストがないため、これらの使用には少し制限がありすぎると思います...

編集: 2 つのコメント:

  • このクラスの機能の 1 つは、特定の単純なタイプのデータの集計と、入力に基づく計算 (合計など) を実行する機能です。生成された残りのテキスト出力もテストせずに、これをテストしたいと思います。
  • 既存のコード ベースに変更を加えることができればよかったのですが、それはリファクタリングしたくないレガシー コードの非常に大きなチャンクです。そのため、模擬サービスの導入や小さなピースのテストはできなくなります。
4

5 に答える 5

2

おそらくこれは、より低いレベルでテストする必要があることを示していますか?つまり、出力全体ではなく、貢献するコンポーネントをまとめてテストします。不変の入力セットを提供できるように(おそらく必要に応じてモックを使用して)、結果として出力が変更されないように、コード/テストを調整できることを願っています。

いくつかの高レベルのテストが(結果の統合を確認するために)有用であり、おそらく単純な文字列比較(単にものが適切に統合されていることを確認するため)によってそれを行うことができますが、おそらくもっときめ細かく努力する必要があると思いますレベル。

そうでなければ、diffのようなツールが必要になるかもしれませんが、このライブラリは便利なようです。

于 2013-01-10T11:53:27.783 に答える
1

これは Groovy の強みの 1 つであるため、 Groovyを使用して単体テストを記述します。

しかし、Groovy は XML の処理にも優れています。

いくつかの XML 属性を要約するための小さな例:

// multiline string, very complex XML content :-)
def input = '''\
<list>
    <summand value='13' time='10:40' text='Compare me!'/>
    <summand value='1' />
    <summand value='4' />
    <summand value='2' />
    <summand value='7' />
</list>'''

// reading XML via XmlSlurper
def list = new XmlSlurper().parseText(input)

// Prints 13
println list.summand[0].@value

// collect all summand values, prints 27
println list.summand.collect { it.@value.toInteger() }.sum()

MEAP Making Java Groovyでテストに関する優れたチュートリアルを見つけるか、このプレゼンテーションを参照してください。

Groovy にはテンプレートのサポートもあります。ただし、XML サポートを使用すると、タグのコンテンツ全体ではなく、特定の属性のみを比較して、言及したタイムスタンプなどの一部の属性をスキップすることが非常に簡単になります。したがって、テンプレートを比較する必要はありません。例として、このソースを上記のスクリプトに追加します。

// compare the first summand tag, skipping the time attribute
assert [list.summand[0].@value.toInteger(), list.summand[0].@text] == [13, 'Compare me!']

Groovy を学ぶには、Groovy Koansをお勧めします。Groovy テストを Maven Java プロジェクトに追加するも参照してください。

更新:
XML を相互に比較するのではなく、回答で説明したように単一の値を単体テストします。しかし、完全な方法で行く場合は、次のアプローチを使用します。

  • ビジネス ロジックから XML を取得する
  • 一時的な削除 (Groovy と比較できない値)
  • 比較できない値なしで GStringTemplateEngine (上記のリンクを参照) からテンプレートを生成します
  • http://xmlunit.sourceforge.net/で両方の XML を比較してください。ページの最後に、XmlSlurper を使用した XML の更新
    に関する例があります。
于 2013-01-20T13:00:44.347 に答える
0

出力XMLをオブジェクトツリーに変換するツールを使用して解析することをお勧めします。次に、XML文字列の代わりにオブジェクトツリーを評価し、関心のある部分のみにassertステートメントを記述できます。また、要素の数を数えるなど、文字列ツールでは不可能なテストを実行することもできます。

出力のXSDがある場合は、たとえばXMLBeansまたはJABXを使用できます。XSDがない場合は、SAXに基づいてオートマトンを作成するか、XPath式を使用してXMLツリーの特定の部分を選択できます。

于 2013-01-19T17:00:55.480 に答える
0

何を達成する必要があるか、メッセージの出力形式などについての情報が少なすぎると思います。ただし、テストについて話しているので、テストしたいデータに関する十分な情報があると思いますあなたのコードベースに対して。

クラスが安定した出力を生成する場合 (つまり、同じ入力に対して常に同じ出力を生成する場合)、テストしたい特定のデータ セットに対して何らかのテンプレートを作成したい場合があります (たとえば、Velocityを使用) 。 . クラスへの入力に含まれるデータをテンプレートにも適用します。テストされたクラスの出力に応じて、テンプレートが生成したものが含まれているかどうかをテストするか、(これが実行できない場合は) テンプレートが生成したものに対して DIFF ツールを使用することができます。

出力が人間が読めるテキストである場合、たとえば Lucene でインデックスを作成し、一致するものを検索することが解決策になるでしょうか? そうでない場合でも、テンプレートの結果または定義済みの出力をあいまい検索アルゴリズムと照合することが実行可能なオプションになる可能性があります。

答えなければならない 1 つの質問は、基礎となるコードベースのリファクタリングが (特に長期的に) 安価な作業にならないかどうかです。

出力をテストする代わりに、基礎となるコードの動作を ( Mockitoを使用して) テストすることも検討しましたか? これはあなたが扱っているレガシーコードであるため、はるかに難しいと思いますが、実行可能でしょうか? PowerMockを使用して強化することもできます。これにより、静的メソッドやその他の魔法をモックできます。通常はレガシー コードで便利です。

于 2013-01-19T16:36:49.033 に答える
-1

PowerMock と一緒に Mockito を使用して、コードの分離された部分をテストできます。PowerMock を使用すると、新しいインスタンスの作成をモック オブジェクトに置き換えたり、静的なプライベート メソッドやクラスをモック/置き換えたり、つまりすべてを行うことができます。この組み合わせは、全体をテストすることなく、コードの個別の部分をテストするのに十分強力であることが証明されるはずです。

多くの異なる部分を含む制御されていないフローで 1 MB のファイルを実行する場合、ユニット テストを呼び出すことはできないと思います。

于 2013-01-19T19:29:40.020 に答える