Параллельное программное обеспечение поблочного тестирования - что Вы делаете?

Поскольку программное обеспечение становится более параллельным, как Вы обрабатываете тестирование базового поведения типа с Вашими модульными тестами (не параллельное поведение, просто базовое поведение)?

В добрые старые времена у Вас был тип, Вы назвали его, и Вы проверили также, что он возвратил и/или что другие вещи он назвал.

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

Как Вы имеете дело с этим? Вы абстрагируете/вводите параллельный планировщик (например, абстрагируете Библиотеку Параллели Задачи и обеспечиваете фальшивку/насмешку в модульных тестах)?

С какими ресурсами Вы столкнулись, который помог Вам?


Править

Я отредактировал вопрос подчеркнуть тестирование нормального поведения типа (игнорирующий любой параллельный механизм, используется для использования в своих интересах многоядерный, например, TPL),


12
задан Steve Dunn 29 July 2010 в 15:54
поделиться

6 ответов

Область модульного тестирования на условия гонки и тупики относительно новая и не имеет хороших инструментов.

Я знаю два таких инструмента, оба на ранних стадиях альфа/бета:

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

3
ответ дан 2 December 2019 в 21:22
поделиться

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

Для интеграционных тестов я просто явно вызываю фоновую задачу, а затем проверяю ожидания после этого.

В Cucumber это выглядит так:

When I press "Register"
And the email sending script is run
Then I should have an email
0
ответ дан 2 December 2019 в 21:22
поделиться

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

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

1
ответ дан 2 December 2019 в 21:22
поделиться

Отказ от ответственности: Я работаю в Corensic, небольшом стартапе в Сиэтле. У нас есть инструмент под названием Jinx, который предназначен для обнаружения ошибок параллелизма в вашем коде. Пока мы находимся в бета-версии, он бесплатен, так что вы, возможно, захотите проверить его. ( http://www.corensic.com/ )

В двух словах, Jinx - это очень тонкий гипервизор, который при активации проскальзывает между процессором и операционной системой. Затем Jinx интеллектуально берет фрагменты выполнения и запускает симуляцию различных таймингов потоков для поиска ошибок. Когда мы находим определенное время выполнения потока, которое приводит к возникновению ошибки, мы делаем это время "реальностью" на вашей машине (например, если вы используете Visual Studio, отладчик остановится в этой точке). Затем мы указываем область в вашем коде, где была вызвана ошибка. В Jinx нет ложных срабатываний. Если он обнаруживает ошибку, то это точно ошибка.

Jinx работает в Linux и Windows, как в родном, так и в управляемом коде. Он не зависит от языка и платформы приложения и может работать со всеми существующими инструментами.

Если вы попробуете его, пожалуйста, пришлите нам отзывы о том, что работает и не работает. Мы запустили Jinx в некоторых крупных проектах с открытым исходным кодом и уже видим ситуации, когда Jinx может найти ошибки в 50-100 раз быстрее, чем простое стресс-тестирование кода.

5
ответ дан 2 December 2019 в 21:22
поделиться

Я рекомендую взять копию Growing Object Oriented Software от Freeman and Pryce . Последние несколько глав очень поучительны и посвящены этой конкретной теме. Он также вводит некоторую терминологию, которая помогает определить обозначения для обсуждения.

Подводя итог .... Их основная идея состоит в том, чтобы разделить функциональные возможности и аспекты параллелизма / синхронизации .

  • Сначала протестируйте функциональную часть в одном синхронном потоке, как обычный объект.
  • Как только вы определите функциональную часть. Можно перейти к параллельному аспекту. Для этого вам нужно подумать и придумать « наблюдаемые инварианты с параллелизмом » для вашего объекта, напримерсчетчик должен быть равен количеству вызовов метода. После того, как вы определили инварианты, вы можете написать стресс-тесты, которые запускают несколько потоков и т.д., чтобы попытаться сломать ваши инварианты. Стресс-тесты подтверждают ваши инварианты.
  • Наконец, в качестве дополнительной защиты запустите инструменты или статический анализ для поиска ошибок.

Для пассивных объектов, то есть кода, который будет вызываться от клиентов в разных потоках: ваш тест должен имитировать клиентов, запуская свои собственные потоки. Затем вам нужно будет выбрать между прослушиванием уведомлений или методом выборки / опроса для синхронизации ваших тестов с SUT.

  • Вы можете заблокировать, пока не получите ожидаемое уведомление.
  • Опросить определенные наблюдаемые побочные эффекты с разумным таймаутом.
4
ответ дан 2 December 2019 в 21:22
поделиться

Учитывая, что ваш TPL будет иметь свой отдельный юнит-тест, вам не нужно проверять это.

Учитывая, что я пишу два теста для каждого модуля:
1) Однопоточный модульный тест, который использует некоторую переменную окружения или #define для включения TPL, чтобы я мог проверить свой модуль на функциональную корректность.
2) Стресс-тест, который запускает модуль в его потоковом развертываемом режиме. Этот тест пытается найти проблемы параллелизма и должен использовать много случайных данных.

Второй тест часто включает много модулей и поэтому, вероятно, является скорее интеграционным/системным тестом.

0
ответ дан 2 December 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: