Многопоточность модульного теста - PullRequest
1 голос
/ 08 января 2009

Чтобы протестировать проблемы параллелизма, я хочу вызывать один и тот же метод в двух разных потоках в одно и то же время, используя модульный тест. На самом деле, я, вероятно, хочу вызвать один и тот же метод в нескольких потоках одновременно.

Я использую встроенный тестер Microsoft для VS2008.

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

Кто-нибудь делал это раньше? Я принимаю здесь разумный подход?

Ответы [ 4 ]

5 голосов
/ 08 января 2009

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

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

3 голосов
/ 08 января 2009

Проблема такого подхода заключается в том, что результаты не воспроизводимы. Таким образом, если бы в вашем коде была ошибка, многократный вызов одного и того же теста в некоторых случаях приводил бы к (например) взаимоблокировке, а в других - нет.

1 голос
/ 09 января 2009

Если вы используете модульные тесты для тестирования многопоточного кода, вы, вероятно, делаете это неправильно.

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

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

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

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

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

Подводя итог, не все должны быть проверены модулем; Проверочные тесты - хороший способ убедиться, что ваша многопоточная коллекция действительно поточно-ориентирована, а стресс-тестирование отлично подходит для обнаружения ошибок в многопоточном коде.

0 голосов
/ 08 января 2009

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

Если вы пытаетесь убедиться, что нет тупиков, вы можете взглянуть на гонщика typemock: http://www.typemock.com/learn_about_typemock_racer.html У меня нулевой опыт, но похоже, что он может обнаружить много тупиков.

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