web-dev-qa-db-ja.com

MSTestに単一のスレッドを使用させる

このテストフィクスチャを考えると:

[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に単一のスレッドを使用してそれらを実行させる方法はありますか?

34
Paul Stovell

私は、nHibernateを多用し、スレッドセーフではない(問題ではない、ただそうではない)ISessionで、MSTestをシングルスレッドモードで実行するために何時間も戦いました。

私と私のチームの知る限りでは、MSTestをシングルスレッドモードで実行することはできないため、MSTestのマルチスレッドの性質をサポートするコードを書くことに多くの時間を費やすことになりました。

12
detroitpro

私はロックでこの問題を解決しました:

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

もちろん、これは基本テストクラスに抽出して再利用できます。

22
BartoszKP

私たちは、互いに分離されたテストを作成するように努めています。それらの多くは、データベースの状態を設定し、後でそれを復元することによってこれを実現します。ほとんどのテストは異なるデータを設定しますが、テストのコード作成者が最初のデータが一意であることを確認しない限り(つまり、別の主キーと同じ主キーを使用しない限り、実行中に約10,000が衝突する可能性がかなりあります)同様のことを行うテスト)。これは率直に言って管理不能であり、2回目に合格するテストの失敗が時折発生します。これは、厳密に順番にテストを実行することを回避する衝突が原因であると確信しています。

2
haughtonomous

あなたはからあなたのテストクラスを導き出すことができます

public class LinearTest
{
    private static readonly object SyncRoot = new object();

    [TestInitialize]
    public void Initialize()
    {
        Monitor.Enter(SyncRoot);
    }

    [TestCleanup]
    public void Cleanup()
    {
        Monitor.Exit(SyncRoot);
    }
}
2
mehmet mecek

それは警官の答えですが、実際にはコードをスレッドセーフにすることをお勧めします。 MSTestの動作は、Richardが指摘したように分離を保証することです。ユニットテストで問題が発生することにより、将来的にいくつかの問題が発生する可能性があることを証明しています。

それらを無視するか、NUnitを使用するか、またはそれらを処理してMSTestを引き続き使用することができます。

1
Mitch Denny

根本的な問題はパイプの名前が問題であるということなので、私は少し異なるアプローチを試しました。そこで、プログラムで使用しているものから派生した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); 
  }
}

複数のコアとスレッドで実行できるため、少し高速に見えます...

0
kfn