web-dev-qa-db-ja.com

TDD:ファイル出力をテストする方法?

TDDは初めてなので、この質問はかなり基本的なものだと思います。

私たちはウェブサイトを構築しており、機能の一部はいくつかのファイル(バイナリファイル:Excel、PDFなど)を生成しています。この機能をどのようにテストすればよいですか?

いくつかの静的ファイルを作成してそれらを生成されたファイルと比較することを考えましたが、バイナリ比較は信頼できません(ファイルの内容は同じでチェックサムが異なる可能性があります)。また、TDDを正しく理解していれば、論理比較はありません基本的に、ファイルの生成に使用するのと同じアルゴリズムを使用する必要があるため、実際には何もテストしません。

この種のことは通常どのように扱われますか?

ライブラリを使用してファイルを解析することでこれを実現しました。すでに利用できるように聞こえるので、これを使用する必要があります。

バイナリファイル全体を比較できたとしても、これはお勧めしません。バイナリ出力全体を比較してさまざまなものをテストする100個のテストがあるとします。次に、各ファイルのタイトルを「Foo」から「Bar」に変更するという新しい要件が発生します。すべての出力ファイルが「Foo」というタイトルを出力していると仮定すると、修正する必要のある100個の壊れたテストがあります。

より良い方法は、他のテストと重複しない1つのテストのみをテストすることです。このコンテキストでは、タイトルのチェックを担当するテストはほんのわずかです。次に、同じ要件が発生した場合、変更する必要があるのは、これらのいくつかのテストのみです。

4
Daniel Kaplan

この種のことは通常どのように扱われますか?

ファイルを単体テストしない。

一般的に、ファイルのコンテンツを定義するいくつかの中間形式があります。期待する中間コンテンツがPDF化されるために送信されていることをテストします。基本的に、すべてを分離しますbut実際に出力をPDFにエンコードします。理想的な世界では、その作業は一部のライブラリーによって行われるため、テストする必要はありません。

現実の世界では、人間がPDFを目視して、それらが適切に形成され、「正しく見える」ことを確認し(そして、異なるプラットフォームのAcrobatに適切にロードするなど)、その内容も確認するようにする必要があります。すべてがTDDに適しているわけではありません。

10
Telastyn

ファイル出力は通常、統合テスト(=いくつかのコンポーネントが一緒に動作している)に属し、ユニットテスト(= 1つのコンポーネントを個別にテストする)には属しません

同じ入力が常に同じ出力を生成するようにPDF生成が実装されている場合は、前の呼び出し結果とバイナリ比較を行う approvaltests を試すことができます。以前の結果がない場合、またはバイナリ比較が異なる場合、古いバージョンと新しいバージョンが同じかどうかをGUIが尋ね、両方のPDFファイルをacrobatリーダーで表示します。

このようにして、出力が変更されるたびに通知されます。例

注意:

pdf-generationが現在の日付を出力に挿入する場合、出力は呼び出しごとに異なります。

Pdf-apiのパラメーターとして日付を指定すると、同じ出力を生成できます。

2
k3b

ファイルをテストする方法はいくつかあります。

  1. バイナリ比較。各テストの「ゴールデン」結果ファイルを出力します。手動で正しいことを確認してください。保存して、将来のファイル出力と比較します。長所:シンプル。短所:壊れやすい。偽陰性の傾向があります(ファイルに「作成日」などのメタデータが含まれている場合、「ペイロード」データが変更されていない場合でも変更される)。
  2. ファイルの解析。ライブラリを使用して(Excel、PDF、テキスト、...)ファイルを解析します。解析されたデータに対してアサーションを実行します。プロ:バイナリ比較よりも脆弱ではありません。メタデータのフラッターを簡単に回避できます。短所:コーディングがより複雑で複雑です。すべてのファイル形式がすぐに解析できるわけではなく、出力の興味深い機能が簡潔で説明的なテストアサーションのセットに適しているわけでもありません。
  3. レンダリングされた比較。ファイルを出力します。レンダリングエンジンを使用して、ファイルを比較可能な表現(ロスレスイメージファイルなど)に変換します。プロ:純粋なバイナリ比較よりも脆弱でなく、解析とアサーションよりもコーディングが簡単です。メタデータではなく「ペイロード」に簡単に焦点を当てます。短所:レンダラーとレンダリング環境(特定のレンダラーバージョンを含む)に依存します。単純なバイナリ比較と同じ「ゴールデンイメージ」ファイルが必要です。関連する部分のみを位置合わせして比較するには、トリミング、フィルタリング、およびソート操作が必要な場合があります。
2
Jonathan Eunice

出力ファイルのテストは常に難しいことです。Webからのファイルのダウンロードやコンソールへの出力をテストする場合も同様です。

自問する必要がある質問の1つは、「ファイルが必要になるまでどこまでテストできるか」です。ほとんどのロジックは、なんらかの置換コードまたは単純なテキストファイルジェネレーターを使用してテストできます。
あなたの質問を見ると、複数のファイルを生成できるので、データを提供するコードとファイルを生成しているコードの間には、すでに何らかの分離があると思います。したがって、私の答えは、実際のファイルを生成する一種のファクトリーがあるという仮定に基づいています。

あなたが自問できる質問は次のとおりです:ファクトリーはどれほど複雑で、多くの追加ロジックが含まれていますか、それともファイルを作成している別のライブラリーから関数を呼び出しているだけですか?
ファクトリに多くのロジックがある場合、これはすべての種類の出力で同じですか、各出力で異なりますか?同じ場合は、ファクトリーからリファクタリングするか、テストしやすい形式(プレーンテキストファイルなど)を追加することを検討する必要があります。
ライブラリを呼び出すだけの場合、本当に自動的にテストする必要がありますか?使用しているライブラリをテストしませんか?

したがって、基本的には、できるだけ複雑なファイルを作成する必要がないテストを行います。 htmlやjsonを含むプレーンテキストファイルは、読み取り可能で比較可能であるため、テストが比較的簡単です。バイナリ出力をテストするには、テストする単純なサンプルファイルを生成し、ファクトリを使用して同じファイルを生成し、バイトレベルでファイルをテストするテストを作成します。同じパラメータで生成されたものは、同じファイルを何度も生成するはずです。

2
David Perfors