2016-05-20 10 views
3

説明複数のユニットテストを実行し、同じファイルをコピーすると、すべてのユニットテストが失敗

私はどの宛先にコピー元からファイルをする方法、のユニットテストを書いています。基本的には、このコードは、(test.png)、私のユニットテストプロジェクトのResourcesのフォルダにあります。私のユニットテストプロジェクトで

public void MyMethod() 
{ 
    // ... 
    File.Copy(source, destination, true); 
    // ... 
} 

を、私はテストファイルを持っています。そして私はCopy to OutputプロパティをAlwaysに設定しました。

私はこの方法をテストしている3つの単体テストを持っています。

ファイルをコピーするコードの行にヒットしたとき:source = "Resources\\test.png"

問題は

私は個別にユニットテストを実行し、それらはすべて合格し、すべてが正常です。私は、Visual Studioのすべてのテストを実行すると はしかし、私はこの実行時エラーを取得し、ユニットテストは失敗:

System.IO.DirectoryNotFoundException

パスの一部を見つけることができませんでした「リソース\テスト.png '

私の考えVisual Studioは別のスレッドで同時に各ユニットテストを実行し、それらのすべてが同時に同じファイルにアクセスするため...おそらく

  • を(更新)?

  • 私はすべての単体テストについて、Visual Studioはbin/Debugbin/Releaseのフォルダをクリーニングしていると思います。次に、必要なすべてのプロジェクトファイルをそのフォルダにコピーします。これにより、ファイルが実際に存在しないことがあります。

質問

はどうすればこの問題を解決することができますか?

これを解決する設定はありますか?

複数の単体テストが同じファイルにアクセスしているときに、Visual Studio(およびTeam City)ですべての単体テストを実行するにはどうすればよいですか?

+0

をあなたがそれらの3つのテストの全体のコードを共有することができればそれが役立つかもしれません。 –

答えて

1

単体テストをバッチで実行しているときにテストファイルの相対パスを使用していたため、テストランナーの作業ディレクトリが個々のテストを実行するときと異なり、ディレクトリを見つけることができませんでした。

だから私は、テストファイルへの絶対パスを構築するために、この機能を使用:

private string GetFilePath([CallerFilePath] string path = "") 
    { 
     return path; 
    } 

その後:

string projectDir = Path.GetDirectoryName(GetFilePath()); 
    string testFile = Path.Combine(projectDir, @"Resources\test.png"; 
0

明示的な「ディレクトリが見つかりません」という例外がある場合、テストされたメソッドの1つがディレクトリを変更するという問題があると推測します。ファイルのロックや並行性の問題が、このような動作を引き起こす可能性はほとんどありません。

+0

ユニットテストでは、少なくとも自分のコード内のディレクトリを変更していません。私は質問を更新しました。ありがとう。 –

1

同じファイルにアクセスすることは問題ではありません。ファイルを削除するcleanUp Fixture(TestSuiteレベル)がないことを確認してください。例外から、テスト実行後にファイルが削除されているように見えるためです。

また、並行読み取り操作は問題なく、完全に合法です。あなたの単体テストがファイルを上書きしている場合、それは問題です。

+0

私は 'destination'を削除するクリーンアップを持っています。しかし、 'source = 'Resources \\ test.png''は常に固定であり、決して削除されません。 –

2

MSDN: Executing Unit Tests in parallel on a multi-CPU/core machineの指示に従って、parallelTestCount1に設定することで、マルチスレッドの問題を排除できます。テストに合格すれば、問題を絞り込んだことになります。そして私は、これは、より可能性の高いシナリオだと思う - - あなたはグループでそれらを実行すると、あなたのテストがまだ失敗している場合

しかし、その後、私のアドバイスは、それらのテストを共有している任意の状態をチェックすることです。あなたが記述パターンは、典型的には(誤って)共有状態、その状態は、1つの以上のテストが失敗し、それらのテストによって修飾されているれている試験によって示される症状である(すなわち、分離して通過するときにない分離に失敗します)。

0

ユニットテストあなたは本当にあなたがそのコードを書いていないので、File.Copy(またはFileクラスのメソッドのいずれか)が働いていたかどうかをテストするべきではない場合。代わりに、あなたはあなたのコードは、ファイルの種類(すなわち、それは、正しいソースファイル名を渡すdesinationファイルの名前と、「コピー」と呼ばれるとき値を上書きしなかった)と正しく相互作用するかどうかテストする必要があります。最初に、Fileクラスのインタフェースとそのインタフェースを実装するラッパーを作成します。

public interface IFileWrapper 
{ 
    void Copy(string sourceFileName,string destFileName,bool overwrite); 
    //Other required file system methods and properties here... 
} 

public class FileWrapper : IFileWrapper 
{ 
    public void Copy(string sourceFileName, string destFileName, bool overwrite) 
    { 
     File.Copy(sourceFileName, destFileName, overwrite); 
    } 
} 

あなたは、あなたがテストしているクラスを作るべきではIFileWrapperパラメータ(dependency injection)が含まれます。単体テストでは、Moqのようなモックフレームワークを使うことができます。あるいは、あなた自身のモックを書くこともできます。 MockFileWrapperに渡しIFileWrapperパラメータとしてではなく、あなたのユニットテストでは、実際の実装では

public class MockFileWrapper : IFileWrapper 
{ 
    public string SoureFileName { get; set; } 
    public string DestFileName { get; set; } 
    public bool Overwrite { get; set; } 
    public void Copy(string sourceFileName, string destFileName, bool overwrite) 
    { 
     SoureFileName = sourceFileName; 
     DestFileName = destFileName; 
     Overwrite = overwrite; 
    } 
} 

はのFileWrapperに渡します。ユニットテストでmockFileWrapperのプロパティをチェックすることで、クラスの呼び出しがCopyを呼び出すかどうか、そして呼び出される方法を判断できるようになりました。単体テスト間で実際のファイルを共有していないので、テストが状態を共有したり、ファイルをロックする可能性はありません。

関連する問題