Заставить MSTest использовать один поток - PullRequest
33 голосов
/ 18 февраля 2011

Для данного тестового приспособления:

[TestClass]
public class MSTestThreads
{
    [TestMethod]
    public void Test1()
    {
        Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
    }

    [TestMethod]
    public void Test2()
    {
        Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
    }
}

При запуске теста с помощью MSTest через Visual Studio или командную строку выводятся два разных номера потока (но они все равно запускаются последовательно).

Есть лиспособ заставить MSTest запускать их, используя один поток?

Ответы [ 6 ]

20 голосов
/ 28 июня 2014

Я решил эту проблему с блокировкой:

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

Это, конечно, можно извлечь в базовый тестовый класс и использовать повторно.

12 голосов
/ 18 февраля 2011

Я боролся за бесконечные часы за то, чтобы заставить MSTest работать в однопоточном режиме в большом проекте, который интенсивно использовал nHibernate, и он не безопасен для потоков (не проблема, это просто не так) 1002 *

Мы потратили больше времени на написание кода для поддержки многопоточной природы MSTest, поскольку, насколько мне известно, и моей команды, невозможно запустить MSTest в однопоточном режиме.

2 голосов
/ 19 апреля 2016

Вы можете получить свой тестовый класс от

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 голосов
/ 14 июня 2013

Мы стараемся разглядеть тесты изолированно друг от друга. Многие из них достигают этого, устанавливая состояние базы данных, а затем восстанавливая ее. Несмотря на то, что в большинстве случаев тесты устанавливают разные данные, при примерно 10000 в прогоне существует реальная вероятность коллизии, если только автор кода теста не позаботится о том, чтобы его исходные данные были уникальными (т. Е. Не использовались те же первичные ключи, что и другие). пробуй делать что-то похожее). Честно говоря, это неуправляемо, и мы иногда получаем неудачные тесты, которые проходят второй раз. Я вполне уверен, что это вызвано коллизиями, которых можно было бы избежать, если бы тесты выполнялись строго последовательно.

1 голос
/ 19 февраля 2011

Несмотря на то, что это ответ на все вопросы, я бы посоветовал вам сделать ваш код безопасным для потоков.Поведение MSTest заключается в обеспечении изоляции, как указал Ричард.Встречаясь с проблемами с вашими юнит-тестами, вы доказываете, что в будущем могут возникнуть некоторые проблемы.

Вы можете игнорировать их, использовать NUnit или иметь дело с ними и продолжать использовать MSTest.

0 голосов
/ 11 декабря 2017

Я попробовал немного другой подход, потому что основная проблема заключается в том, что имена каналов являются проблемой. Поэтому я сделал поддельный пайп, выведенный из того, который я использую в программе. И назвал трубу с именем испытаний.

[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); 
  }
}

Это выглядит немного быстрее, так как мы можем работать на нескольких ядрах и потоках ...

...