このテストフィクスチャを考えると:
[TestClass]
public class MSTestThreads
{
[TestMethod]
public void Test1()
{
Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
[TestMethod]
public void Test2()
{
Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
Visual StudioまたはコマンドラインからMSTestを使用してテストを実行すると、2つの異なるスレッド番号が出力されます(ただし、いずれにせよ、それらは順番に実行されます)。
MSTestに単一のスレッドを使用してそれらを実行させる方法はありますか?
私は、nHibernateを多用し、スレッドセーフではない(問題ではない、ただそうではない)ISession
で、MSTestをシングルスレッドモードで実行するために何時間も戦いました。
私と私のチームの知る限りでは、MSTestをシングルスレッドモードで実行することはできないため、MSTestのマルチスレッドの性質をサポートするコードを書くことに多くの時間を費やすことになりました。
私はロックでこの問題を解決しました:
public static class IntegrationTestsSynchronization
{
public static readonly object LockObject = new object();
}
[TestClass]
public class ATestCaseClass
{
[TestInitialize]
public void TestInitialize()
{
Monitor.Enter(IntegrationTestsSynchronization.LockObject);
}
[TestCleanup]
public void TestCleanup()
{
Monitor.Exit(IntegrationTestsSynchronization.LockObject);
}
//test methods
}
// possibly other test cases
もちろん、これは基本テストクラスに抽出して再利用できます。
私たちは、互いに分離されたテストを作成するように努めています。それらの多くは、データベースの状態を設定し、後でそれを復元することによってこれを実現します。ほとんどのテストは異なるデータを設定しますが、テストのコード作成者が最初のデータが一意であることを確認しない限り(つまり、別の主キーと同じ主キーを使用しない限り、実行中に約10,000が衝突する可能性がかなりあります)同様のことを行うテスト)。これは率直に言って管理不能であり、2回目に合格するテストの失敗が時折発生します。これは、厳密に順番にテストを実行することを回避する衝突が原因であると確信しています。
あなたはからあなたのテストクラスを導き出すことができます
public class LinearTest
{
private static readonly object SyncRoot = new object();
[TestInitialize]
public void Initialize()
{
Monitor.Enter(SyncRoot);
}
[TestCleanup]
public void Cleanup()
{
Monitor.Exit(SyncRoot);
}
}
それは警官の答えですが、実際にはコードをスレッドセーフにすることをお勧めします。 MSTestの動作は、Richardが指摘したように分離を保証することです。ユニットテストで問題が発生することにより、将来的にいくつかの問題が発生する可能性があることを証明しています。
それらを無視するか、NUnitを使用するか、またはそれらを処理してMSTestを引き続き使用することができます。
根本的な問題はパイプの名前が問題であるということなので、私は少し異なるアプローチを試しました。そこで、プログラムで使用しているものから派生したfakePipeを作成しました。そして、テスト名でパイプに名前を付けました。
[TestClass]
public class PipeCommunicationContractTests {
private PipeDummy pipe;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext { get; set; }
[TestInitialize]
public void TestInitialize() {
pipe = new PipeDummy(TestContext.TestName);
pipe.Start();
}
[TestCleanup]
public void TestCleanup() {
{
pipe.Stop();
pipe = null;
}
...
[TestMethod]
public void CallXxOnPipeExpectResult(){
var result = pipe.Xx();
Assert.AreEqual("Result",result);
}
}
複数のコアとスレッドで実行できるため、少し高速に見えます...