2011-07-07 20 views
2

新しいファイルの作成と読み込みに依存するいくつかのJUnitテストがあります。しかし、ファイルが正しく作成されないという問題があります。しかし、この間違いは起こります。第二のファイルオブジェクトは、file_2は、作成されませんでしということです新しいファイルの作成時にJUnitテストが失敗する

@Test 
public void test_3() throws Exception { 

    // Deletes files in tmp test dir 

    File tempDir = new File(TEST_ROOT, "tmp.dir"); 
    if (tempDir.exists()) { 
     for (File f : tempDir.listFiles()) { 
      f.delete(); 
     } 
    } else { 
     tempDir.mkdir(); 
    } 

    File file_1 = new File(tempDir, "file1"); 
    FileWriter out_1 = new FileWriter(file_1); 
    out_1.append("# File 1"); 
    out_1.close(); 

    File file_2 = new File(tempDir, "file2"); 
    FileWriter out_2 = new FileWriter(file_2); 
    out_2.append("# File 2"); 
    out_2.close(); 

    File file_3 = new File(tempDir, "fileXXX"); 
    FileWriter out_3 = new FileWriter(file_3); 
    out_3.append("# File 3"); 
    out_3.close(); 
      .... 

ザ・は失敗:

この

はコードです。時々。それで、書き込むと、 FileNotFoundExceptionがスローされます。

  • このテストケースだけを実行すると、すべて正常に動作します。
  • このテストファイルを約40件のテストケースで実行すると、現在の月周期に応じて失敗し、動作することがあります。
  • いくつかの10 * 40のテストケースで構成されるテストスイート全体を実行すると、常に失敗します。

我々は試してみました

  • 追加スリープ(5秒)file_2.exists()までループが真であるが、ループはSecurityExceptionが、IOExceptionがあってもスロー可能を引く
  • を停止したことがないながら加えるnew File、何も
  • 後我々はNew File(..)を行うが、何も捕まえていない。

すべてのファイルが作成されていますが、file_1より前にfile_2が作成されており、作成時間のチェックに失敗しました。

また、file_1.createNewFile()を追加しようとしましたが、常にtrueを返します。

何が起こっているのですか?実際のファイルに依存するテストを行うにはどうすればよいのですか?

これは、Java 1.5と1.6の両方、Windows 7とLinuxでもテストされています。観察することができる唯一の違いは、時々、同様のテストケースの前に失敗し、時には代わりにfile_1作成されていないということです

私たちは、新しい変化を試みた

更新:

File file_2 = new File(tempDir, "file2"); 
while (!file_2.canRead()) { 
    Thread.sleep(500); 
    try { 
     file_2.createNewFile(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

この結果を多くの種類の例外:タイプの例外:

java.io.IOException: Access is denied 
at java.io.WinNTFileSystem.createFileExclusively(Native Method) 
at java.io.File.createNewFile(File.java:883) 

...最終的には、ファイルが作成されます。

+1

は実際にテストのファイル作成ですか? @Beforeで注釈が付けられた設定メソッドでファイルを作成し、@Afterで注釈を付けられたティアダウンメソッドでファイルを削除しようとしないのはなぜですか?たぶんこれは違いを生むだろうか? – peshkira

+0

良いコメントですが、テストファイルにはいくつかのテストケースが含まれており、その一部だけが削除/作成されるファイルに依存しています。もちろん、ファイルに依存するテストを分割して別々のテストファイルに入れることもできます。 しかし、実際に何かを変える前に@で作成していますか? – Fredrik

+0

わかりませんが、傷つけることはありません。とにかくあなたのテストを分割することも良いです。 ファイルの作成時またはFileWriterの作成時にのみIOExceptionをキャッチしようとしましたか?テストが失敗していることを除いて、他の例外はありませんか? – peshkira

答えて

1

ファイル名をハードコードしないでください。ランダムな名前を使用してください。これは、発生する可能性があるさまざまな外部状況(同じファイルへの複数のアクセス権、アクセス許可、ファイルシステムエラー、ロックの問題など)から自分自身を抽象化する唯一の方法です。

スリープ()を使用するか再試行すると、将来何らかの点で奇妙なエラーが発生することが保証されます。

2

複数のインスタンスが同時に実行されていますか? javaw.exeが実行されている余分なインスタンスがないか確認してください。一度に複数のプログラムが同じファイルを扱うと、非常に素早く非常にうまくいくことがあります。

ハンドルでファイルの作成/削除を行う可能性のあるウイルス対策ソフトウェアなどを実行していますか?

+0

良いアイデア。いいえ、テストのインスタンスは1つだけです。私たちはEclipse(Windows)やJenkins(linux)の自動テストの一環としてこれをテストしています – Fredrik

+0

どのユーザーがプロセスを実行していますか?このユーザーは、ファイルを作成するディレクトリに対する読み取り/書き込みアクセス権を持っていますか? –

0

私はいくつかのグーグルを行い、this lucene bugthis board questionに基づいて、ファイルロックやファイルを使用している他のプロセスで問題が発生している可能性があるようです。

これをClearCaseで実行しているので、ファイルの作成時にClearCaseが何らかの索引付けなどを行うと思われます。ファイルが読み込み可能になるまで繰り返すループを追加することで問題が解決されました。しかし、非常に醜い解決策。

1

File#createTempFileを試してください。これは、少なくともロックを保持している同じ名前のファイルがないことを保証します。

関連する問題