Юнит-тестирование потоков? - PullRequest
7 голосов
/ 15 декабря 2010

Мне просто нужно выполнить модульное тестирование некоторых методов, подобных этому:

public void start()
{
    myThread.Start();
}

public void stop()
{
    myThread.Abort();
}

Как я могу это сделать? Я могу вызвать метод start и проверить IsAlive == true, но затем поток продолжает работать в фоновом режиме и вызывает свой собственный метод. Другой способ - я вызываю start, а затем немедленно останавливаюсь, но это не так, потому что я бы тестировал две вещи. Это так просто, но аааа!

Ответы [ 5 ]

7 голосов
/ 15 декабря 2010

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

Книга xUnit Test Patterns хорошо описывает это. Это даже шаблон - Humble Object . Там все объясняется лучше, чем я.

2 голосов
/ 15 декабря 2010

Я согласен с BnWasteland, что для данного примера кода можно протестировать только то, что System.Threading.Thread.Start и System.Threading.Thread.Abort работают правильно. Поэтому было бы разумно предположить, что они есть, и сосредоточиться на собственном коде приложения. Тогда у вас есть два домена:

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

2) Убедитесь, что многопоточная инфраструктура работает должным образом.

(2) больше относится к категории тестирования интеграции, но никто не запрещает использовать для этого инфраструктуру Unit-tesitng. И в этом случае хорошо выполнить Start / Stop и даже сделать это несколько раз с некоторыми рандомизированными рабочими нагрузками, просто чтобы убедиться, что система ведет себя и выполняет свою работу. Это, очевидно, относится к «более длительному» испытательному костюму, который не нужно выполнять при каждой регистрации.

2 голосов
/ 15 декабря 2010

Хорошей идеей является сделать вещи, которые будут зависеть от времени, синхронными для целей тестирования. (Действительно, это хорошая идея - локализовать взаимодействия, зависящие от времени, даже при отсутствии тестирования.)

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

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

2 голосов
/ 15 декабря 2010

Используйте thread synchronization и wait handles для ожидания запущенных потоков.

Синхронизация потоков (Руководство по программированию в C #)

0 голосов
/ 15 декабря 2010

Зачем вам нужно юнит-тестирование этих методов? Что вы пытаетесь проверить? Сломаются ли другие тесты, если то, что вы пытаетесь проверить, не соответствует действительности? (Т.е. это покрыто другими тестами?)

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

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