2010-12-14 4 views
8

При использовании моего приложения я наткнулся на состояние гонки в некотором коде, который использует NSOperationQueue для выполнения задач асинхронно после событий, вызванных пользователем. Я знаю, как исправить состояние гонки, так как это глупая ошибка дизайна, в которую я не буду вникать, но я хотел бы доказать ошибку с тестовым примером (чтобы он не возвращался во время оптимизации/рефакторинга по линии). Это меня насторожило. Как вы можете протестировать что-то многопоточное, особенно когда целью теста является создание условия гонки?Единичное тестирование кода на основе потоков? Принуждение состояния гонки

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

+0

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

ответ

4

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

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

Затем сделайте все это условным для глобального флага, установленного тестовым примером.

+3

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

+0

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

+0

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

Смежные вопросы