50

以下を使用して、junit でテキスト ファイルを比較しています。

public static void assertReaders(BufferedReader expected,
          BufferedReader actual) throws IOException {
    String line;
    while ((line = expected.readLine()) != null) {
        assertEquals(line, actual.readLine());
    }

    assertNull("Actual had more lines then the expected.", actual.readLine());
    assertNull("Expected had more lines then the actual.", expected.readLine());
}

これは、テキスト ファイルを比較する良い方法ですか? 何が好ましいですか?

4

9 に答える 9

47

ファイルがまったく同じかどうかを確認する簡単な方法の 1 つを次に示します。

assertEquals("The files differ!", 
    FileUtils.readFileToString(file1, "utf-8"), 
    FileUtils.readFileToString(file2, "utf-8"));

file1file2Fileインスタンスであり、FileUtilsApache Commons IOからのものです。

独自のコードを維持する必要はほとんどありません。これは常にプラスです。:) プロジェクトですでに Apache Commons を使用している場合は、非常に簡単です。しかし、 mark's solution のような詳細なエラー メッセージはありません。

編集:
へえ、FileUtilsAPI を詳しく見てみると、さらに簡単な方法があります:

assertTrue("The files differ!", FileUtils.contentEquals(file1, file2));

おまけとして、このバージョンはテキストだけでなく、すべてのファイルで機能します。

于 2009-01-21T21:32:51.287 に答える
31

junit- addonsはそれをうまくサポートしています:FileAssert

次のような例外があります。

junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]
于 2009-01-21T20:36:43.863 に答える
24

以下は、さまざまなサードパーティ Java ライブラリのファイル コンパレータの完全なリストです。

于 2010-06-09T01:18:52.470 に答える
18

2015 年現在、エレガントで包括的なアサーション ライブラリであるAssertJをお勧めします。ファイルの場合、別のファイルに対してアサートできます。

@Test
public void file() {
    File actualFile = new File("actual.txt");
    File expectedFile = new File("expected.txt");
    assertThat(actualFile).hasSameContentAs(expectedFile);
}

またはインライン文字列に対して:

@Test
public void inline() {
    File actualFile = new File("actual.txt");
    assertThat(linesOf(actualFile)).containsExactly(
            "foo 1",
            "foo 2",
            "foo 3"
    );
}

失敗メッセージも非常に有益です。行が異なる場合は、次のようになります。

java.lang.AssertionError: 
File:
  <actual.txt>
and file:
  <expected.txt>
do not have equal content:
line:<2>, 
Expected :foo 2
Actual   :foo 20

ファイルの 1 つに複数の行がある場合は、次のようになります。

java.lang.AssertionError:
File:
  <actual.txt>
and file:
  <expected.txt>
do not have equal content:
line:<4>,
Expected :EOF
Actual   :foo 4
于 2015-03-15T16:03:53.697 に答える
8

java.nio.file2 つのファイルの内容をAPIで簡単に比較。

byte[] file1Bytes = Files.readAllBytes(Paths.get("Path to File 1"));
byte[] file2Bytes = Files.readAllBytes(Paths.get("Path to File 2"));

String file1 = new String(file1Bytes, StandardCharsets.UTF_8);
String file2 = new String(file2Bytes, StandardCharsets.UTF_8);

assertEquals("The content in the strings should match", file1, file2);

または、個々の行を比較したい場合:

List<String> file1 = Files.readAllLines(Paths.get("Path to File 1"));
List<String> file2 = Files.readAllLines(Paths.get("Path to File 2"));

assertEquals(file1.size(), file2.size());

for(int i = 0; i < file1.size(); i++) {
   System.out.println("Comparing line: " + i)
   assertEquals(file1.get(i), file2.get(i));
}
于 2016-03-30T13:01:42.810 に答える
7

Assert.assertThatとハムクレストマッチャー(junit 4.5以降-おそらく4.4)を使用することをお勧めします。

私は次のようなものになってしまいます:

assertThat(fileUnderTest, containsExactText(expectedFile));

私のマッチャーはどこにありますか:

class FileMatcher {
   static Matcher<File> containsExactText(File expectedFile){
      return new TypeSafeMatcher<File>(){
         String failure;
         public boolean matchesSafely(File underTest){
            //create readers for each/convert to strings
            //Your implementation here, something like:
              String line;
              while ((line = expected.readLine()) != null) {
                 Matcher<?> equalsMatcher = CoreMatchers.equalTo(line);
                 String actualLine = actual.readLine();
                 if (!equalsMatcher.matches(actualLine){
                    failure = equalsMatcher.describeFailure(actualLine);
                    return false;
                 }
              }
              //record failures for uneven lines
         }

         public String describeFailure(File underTest);
             return failure;
         }
      }
   }
}

マッチャーの長所:

  • 構成と再利用
  • 通常のコードでの使用とテスト
    • コレクション
    • モックフレームワークで使用されます
    • 一般的な述語関数を使用できます
  • 本当に素晴らしいログ能力
  • 他のマッチャーと組み合わせることができ、説明と障害の説明は正確で正確です

短所:

  • まあ、それはかなり明白ですよね?これは、assertやjunitxよりもはるかに冗長です(この特定の場合)
  • 最大限のメリットを得るには、おそらくハムクレストライブラリを含める必要があります
于 2009-01-21T21:01:04.067 に答える
5

FileUtils確かに良いものです。ファイルが完全に同じであるかどうかを確認するためのさらに別の簡単なアプローチを次に示します。

assertEquals(FileUtils.checksumCRC32(file1), FileUtils.checksumCRC32(file2));

assertEquals()はassertTrue()よりも少し多くのフィードバックを提供しますが、checksumCRC32()の結果は長くなります。だから、それは本質的に役に立たないかもしれません。

于 2011-01-13T18:15:52.317 に答える
4

予想される行数が実際より多い場合は、後でassertNullに到達する前にassertEqualsに失敗します。

ただし、修正はかなり簡単です。

public static void assertReaders(BufferedReader expected,
    BufferedReader actual) throws IOException {
  String expectedLine;
  while ((expectedLine = expected.readLine()) != null) {
    String actualLine = actual.readLine();
    assertNotNull("Expected had more lines then the actual.", actualLine);
    assertEquals(expectedLine, actualLine);
  }
  assertNull("Actual had more lines then the expected.", actual.readLine());
}
于 2009-01-21T20:31:20.460 に答える
0

これは の私自身の実装でありequalFiles、プロジェクトにライブラリを追加する必要はありません。

private static boolean equalFiles(String expectedFileName,
        String resultFileName) {
    boolean equal;
    BufferedReader bExp;
    BufferedReader bRes;
    String expLine ;
    String resLine ;

    equal = false;
    bExp = null ;
    bRes = null ;

    try {
        bExp = new BufferedReader(new FileReader(expectedFileName));
        bRes = new BufferedReader(new FileReader(resultFileName));

        if ((bExp != null) && (bRes != null)) {
            expLine = bExp.readLine() ;
            resLine = bRes.readLine() ;

            equal = ((expLine == null) && (resLine == null)) || ((expLine != null) && expLine.equals(resLine)) ;

            while(equal && expLine != null)
            {
                expLine = bExp.readLine() ;
                resLine = bRes.readLine() ; 
                equal = expLine.equals(resLine) ;
            }
        }
    } catch (Exception e) {

    } finally {
        try {
            if (bExp != null) {
                bExp.close();
            }
            if (bRes != null) {
                bRes.close();
            }
        } catch (Exception e) {
        }

    }

    return equal;

}

AssertTrueそしてそれを使用するには、通常のJUnitメソッドを使用するだけです

assertTrue(equalFiles(expected, output)) ;
于 2015-06-07T05:29:07.517 に答える