web-dev-qa-db-ja.com

XML / JSONシリアル化テストを維持するには?

ファイルに保存された予想出力に対してJSON/XML生成メソッドをテストすることは非常に一般的です(少なくともJava世界では、おそらく他の環境でも))。

たとえば、サービス内の新しいオファーのRSSフィードを生成するメソッドがあります。これには、さまざまな形式(さまざまなRSSコンシューマー向け)とさまざまなオプション(クエリパラメーター、特定の日付、短い形式または長い形式など)があります。

しばらくすると、単体テストで生成された出力に対して検証される20〜30個のファイルがあります。バックログから新しいリクエストが送信されると、期待に応えるために新しいファイルが作成され、新しい単体テストが作成されます。

XMLの出力が変更されると(すべての形式に必須の新しいフィールドが表示されるか、日付形式が変更されます)、テスト用に保存されているすべてのファイルで変更する必要があります。これは、長期的にファイルを維持するのに役に立たなくて苦痛にします。

私の質問は、それを軽減する方法ですか?

単体テストは、生成されたXMLのフラグメントのみを純粋に記述する必要がありますか?たとえば、日付フィールドの個別の単体テスト、新しい必須フィールドの個別など。

XMLを生成するメソッドへのさまざまな出力/形式/クエリパラメータをテストする方法は?結果のXMLが有効な形式であることを確認するためにテストをどのように編成する必要がありますが、同時に単一のプロパティの変更ですべての単体テストを変更する必要はありませんか?

2
Dariusz Mydlarz

あなたが説明する種類のテストはbrittle。正しく指摘したように、小さな変更は既存のテストのかなりの数を壊す可能性があります。しかし、それは設計によるのようなテストは、コードへの最小の変更を打破することを目的としています。これらは、「炭鉱のカナリア」ということわざであり、ユーザーが変更する前にコードの重大な変更を検出するためのものです。

このようなテストは比較的簡単に作成でき、幅広い範囲をカバーするため、多くのテストは必要ありません。必要なのは、テスト中のコードの出力(特定の入力が与えられた場合)を見て、必要に応じて、ユニットテストアサーション(またはファイル)に貼り付けます。これは、新しいコードでテストを中断した場合にも当てはまります。すべての出力を確認し、ユニットテストに貼り付けます。

しかし、そのようなテストは特にが壊れた可能性があることについて何も教えてくれません。実際に何かが壊れただけです。変更点、出力への影響、および新しい出力が望ましいかどうかを判断するのは、あなた次第です。

もう1つの方法は、コードとユニットテストをより小さく独立したチャンクに分割する方法を見つけることです。これにより、コードに変更を加えても、1つまたはいくつかのユニットテストのみが失敗します。そのためには、コードとテストの書き換えに多大な時間と労力を費やす必要があります。結局のところ、これはおそらくより優れた、より保守可能なアプローチです。

トラブルの価値はありますか?あなただけがそれに答えることができます。

5
Robert Harvey

私は数年前からこのような自動テストに取り組んでおり、1つのテストスイートに数百の複雑なXMLファイルが存在しますが、テストの一部が時々壊れたとしても、それらは非常によく保守できます。

私たちのチームは次の方法でこれを達成します:

  1. カスタムの「diff」アルゴリズムを使用して、異なるactualファイルとexpectedファイルの違いを検出します。これらのdiffアルゴリズムは通常、「許容可能な」変更(タイムスタンプの変更、または非常に小さな値によってのみ変更される浮動小数点値など)がある場合に差異を通知しないように、特定のファイル形式に合わせて調整されます。

  2. テストのグループごとに、予想されるファイルをバージョン管理下の1つのフォルダーに保持し(ExpectedDataと呼びます)、バージョン管理下にない別のフォルダーActualDataに実際の出力を生成します。これら2つのフォルダー内のファイルが異なる場合、その種類の違いが意図されていたかどうかを確認します。その場合は、変更されたファイルをActualDataからExpectedDataにコピーするだけです。

そして、はい、単一のプロパティが変更された場合、いくつかのテストデータファイルを更新する必要があるかもしれません。おそらくグループ内すべてですが、そのための労力はかなり少なく、新しいデータファイルが効率的な方法で保存されるバージョン管理に依存しています。前任者との違いとして。これはかなりうまくいきます。

最後に、テストを実行するために単体テストフレームワークを使用しますが、単体テストとは呼びません。これらの種類のテストは、「自動回帰テスト」またはそのようなものと呼ばれます。これらの種類のテストと、外部ファイルなしで動作する実際の単体テストとより細かい粒度を持つことができます。どちらの種類のテストも役立ちます。

2
Doc Brown

テストしている要件は何ですか?

XMLが固有の形式に適合していることが要件である場合、たとえば、SOME-SPEC-1234の場合、はい、その特定の形式に対してテストする必要がありますフォーマット。

データを失うことなく(主にSWによって)書き込んだ内容を読み戻すことができるという要件がある場合、IMOのより良いテストは、それを行うことです。データを作成し、XMLまたはJSONとして一時ファイルに書き込みます。 、それを読み戻して、適切なフィールドを比較します。これは厳密に言えば「ユニット」テストではないため、多少の問題が生じます。 :-) OTOH、これは記述と保守がはるかに簡単です。

0
user949300