Как моделировать параллелизм в юнит-тестах? - PullRequest
14 голосов
/ 08 января 2010

Я довольно новичок в модульном тестировании и сейчас немного экспериментирую с инструментами тестирования Visual Studio.

Мой вопрос заключается в том, как определить утверждения о одновременном поведении в этих тестах. Например. учитывая класс BoundedChan<T>, реализующий ограниченный канал, как я могу указать такие тесты, как

  1. "channel.Send не заблокирует" или
  2. «Если пропускная способность канала будет превышена, channel.Send будет блокироваться до считывания значения»

Есть ли элегантное решение для написания этих утверждений?

Ответы [ 4 ]

6 голосов
/ 08 января 2010

Вот статья в блоге , в которой обсуждается тема; он фокусируется на NUnit.

К сожалению, параллелизм все еще является областью модульного тестирования, которую сложно структурировать. Это не простая проблема, и все же требует, чтобы вы внедрили некоторую собственную логику синхронизации и параллелизма в тесте.

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

4 голосов
/ 08 января 2010

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

В целом, я не рекомендовал бы добавлять модульные тесты в ваши классы для параллельных сценариев. С практикой, я думаю, вы поймете, что у автоматизированных модульных тестов есть одна или несколько «сладких точек» - и что сосредоточение ваших усилий в этих областях (и использование других практик в других областях) дает лучшую рентабельность инвестиций.

Но ваш класс кажется о параллелизме (не могу сказать наверняка, основываясь на предоставленной информации), и поэтому это может быть тот случай, когда вам действительно нужен тест, имитирующий параллелизм.

Вы можете (насколько я знаю) запускать несколько потоков в модульном тесте, если хотите. Но может быть и более простой способ. Подумайте об использовании шаблона Compose Method . Пока мы находимся на этой теме - этот шаблон довольно важен для всех эффективных модульных тестов, а не только с параллелизмом.

1 голос
/ 02 января 2015

Я создал помощника, который может запускать несколько потоков для выполнения одновременных действий. Помощник предоставляет примитивы синхронизации и механизмы регистрации. Он может использоваться в сочетании с любой структурой модульного тестирования. Вот фрагмент кода из модульного теста:

[Test]
public void TwoCodeBlocksInParallelTest()
{
    // This static method runs the provided Action delegates in parallel using threads
    CTestHelper.Run(
        c =>
            {
                Thread.Sleep(1000); // Here should be the code to provide something 
                CTestHelper.AddSequenceStep("Provide"); // We record a sequence step for the expectations after the test
                CTestHelper.SetEvent();
            },
        c =>
            {
                CTestHelper.WaitEvent(); // We wait until we can consume what is provided
                CTestHelper.AddSequenceStep("Consume"); // We record a sequence step for the expectations after the test
            },
        TimeSpan.FromSeconds(10)); // This is a timeout parameter, if the threads are deadlocked or take too long, the threads are terminated and a timeout exception is thrown 

    // After Run() completes we can analyze if the recorded sequence steps are in the correct order
    Expect(CTestHelper.GetSequence(), Is.EqualTo(new[] { "Provide", "Consume" }));
}

Может использоваться для тестирования клиент / сервер или синхронизации в компонентах или просто для запуска потока с таймаутом. Я продолжу улучшать это в ближайшие недели. Вот страница проекта: Помощник по тестированию параллелизма

0 голосов
/ 10 января 2010

Это должно быть интересное чтение -> http://c2.com/cgi-bin/wiki?ExtremeProgrammingChallengeFourteen

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...