Excelファイル(バイナリ)を生成するコードのJUnitテストを書いています。予想される出力を含む別の Excel ファイルがあります。実際のファイルと予想されるファイルを比較する最も簡単な方法は何ですか?
確かに私は自分でコードを書くことができましたが、信頼できるサードパーティ ライブラリ (Spring や Apache Commons など) に既にこれを行っている既存のメソッドがあるかどうか疑問に思っていました。
あなたは私のプロジェクトsimple-excelを使用することを検討するかもしれません。それは仕事をするためにたくさんのHamcrestMatchersを提供します。
次のようなことをすると、
assertThat(actual, WorkbookMatcher.sameWorkbook(expected));
たとえば、
java.lang.AssertionError:
Expected: entire workbook to be equal
but: cell at "C14" contained <"bananas"> expected <nothing>,
cell at "C15" contained <"1,850,000 EUR"> expected <"1,850,000.00 EUR">,
cell at "D16" contained <nothing> expected <"Tue Sep 04 06:30:00">
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
そうすれば、自動化されたテストから実行して、開発中に意味のあるフィードバックを得ることができます。
あなたは私のサイトのこの記事でそれについてもっと読むことができます
これが私がやったことです(重い仕事はDBUnitによって行われます):
/**
* Compares the data in the two Excel files represented by the given input
* streams, closing them on completion
*
* @param expected can't be <code>null</code>
* @param actual can't be <code>null</code>
* @throws Exception
*/
private void compareExcelFiles(InputStream expected, InputStream actual)
throws Exception
{
try {
Assertion.assertEquals(new XlsDataSet(expected), new XlsDataSet(actual));
}
finally {
IOUtils.closeQuietly(expected);
IOUtils.closeQuietly(actual);
}
}
これにより、2 つのファイルのデータが比較され、異なる可能性のある無関係なメタデータによる誤検出のリスクがなくなります。これが誰かに役立つことを願っています。
簡単なファイル比較は、チェックサム(MD5など)を使用するか、両方のファイルを読み取るだけで簡単に実行できます。
ただし、Excelファイルには大量のメタデータが含まれているため、James Burgessが指摘したように、ファイルがバイトごとに同一になることはおそらくありません。したがって、テストには別の種類の比較が必要になります。
どういうわけか、Excelファイルから「標準」フォームを生成することをお勧めします。つまり、生成されたExcelファイルを読み取り、チェックしたい情報のみを保持するより単純な形式(CSVなど)に変換することをお勧めします。次に、「標準形」を使用して、期待される結果と比較できます(もちろん、標準形でも)。
Apache POIは、ファイルの読み取りに役立つ場合があります。
ところで:ファイル全体を読み取ってその正しさを確認することは、通常、単体テストとは見なされません。それは統合テストです...
私は似たようなことをする必要があり、すでにプロジェクトでApache POI ライブラリを使用して Excel ファイルを作成していました。そこで、付属のExcelExtractorインターフェイスを使用して両方のワークブックをテキストの文字列としてエクスポートし、文字列が等しいことを確認しました。.xls 用の HSSF と .xlsx 用の XSSFの両方の実装があります。
文字列にダンプ:
XSSFWorkbook xssfWorkbookA = ...;
String workbookA = new XSSFExcelExtractor(xssfWorkbookA).getText();
ExcelExtractor には、文字列ダンプに含める必要があるものについていくつかのオプションがあります。シート名を含む便利なデフォルトがあることがわかりました。さらに、セルのテキスト コンテンツも含まれます。
私が見つけた最も簡単な方法は、Tika を使用することです。私はこのように使用します:
private void compareXlsx(File expected, File result) throws IOException, TikaException {
Tika tika = new Tika();
String expectedText = tika.parseToString(expected);
String resultText = tika.parseToString(result);
assertEquals(expectedText, resultText);
}
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.13</version>
<scope>test</scope>
</dependency>
javaxdelta を使用して、2 つのファイルが同じかどうかを確認できます。ここから入手できます:
コモンズに何かがあることがわかりました-ioのFileUtils。他の答えをありがとう。
バイナリファイルを比較するには、サイトhttp://www.velocityreviews.com/forums/t123770-re-java-code-for-determining-binary-file-equality.htmlをご覧ください。
虎
コマンドラインから開始でき、Excel ファイルを比較するさまざまな方法をサポートするBeyond Compare 3を使用できます。
Kotlin で最初のシートのコンテンツのみをテストする (簡単に Java に変換できます)。
private fun checkEqualityExcelDocs(doc : XSSFWorkbook, doc1 : XSSFWorkbook) : Boolean{
val mapOfCellDoc = doc.toList().first().toList().flatMap { row -> row.map { Pair(PivotExcelCreator.IndexInThePivotTable(it.rowIndex,it.columnIndex),it.stringCellValue) }}.toMap()
val mapOfCellDoc1 = doc1.toList().first().toList().flatMap { row -> row.map { Pair(PivotExcelCreator.IndexInThePivotTable(it.rowIndex,it.columnIndex),it.stringCellValue) }}.toMap()
if(mapOfCellDoc.size == mapOfCellDoc1.size){
return mapOfCellDoc.entries.all { mapOfCellDoc1.containsKey(it.key) && mapOfCellDoc[it.key] == mapOfCellDoc1[it.key]}
}
return false
}
data class IndexInThePivotTable(val row: Int, val col: Int)
コードに assert を追加します
assertTrue(checkEqualityExcelDocs(expected, actual), "Docs aren't equal!")
ご覧doc.toList().first()
のとおり、ドキュメントの最初のシートのみを取得します。各シートを比較する必要がある場合は、それぞれコードを少し変更してください。
また、"" 空の文字列セルを考慮しないことは非常に良い考えです。この機能は必要ありませんでした (同様に、必要に応じて、この部分を追加するだけです)。
有益な情報にもなります
//first doc I've got from outputstream such way
val out = ByteArrayOutputStream()
//some method which writes excel to outputstream
val firstDoc = XSSFWorkbook(ByteArrayInputStream(out.toByteArray()))
比較するファイルの 2 番目のドキュメント
val secondDoc = XSSFWorkbook(Test::class.java.getClassLoader().getResource("yourfile.xlsx").path)
たぶん... 各ファイルの MD5 ダイジェストを比較しますか? 方法はたくさんあると思います。両方のファイルを開いて、各バイトを比較するだけです。
編集: James は、XLS 形式のメタデータに違いがある可能性があると述べました。おそらく、xls ファイルを生成するために使用したのと同じインターフェイスを使用してそれらを開き、セル間の値を比較する必要がありますか?