Если у меня уже есть интеграционный тест для моей программы, и все они прошли, то у меня хорошее предчувствие, что это сработает. Тогда каковы причины написания / добавления модульных тестов? Так как в любом случае мне уже приходится писать интеграционные тесты, я бы хотел писать модульные тесты только для частей, которые не охвачены интеграционными тестами.
Что я знаю преимущество модульного теста над интеграционным тестом
- Небольшой и, следовательно, быстрый в работе (но добавление нового модуля для тестирования чего-либо уже проверено интеграционным тестом, что означает, что мой общий тестовый набор увеличится и будет работать дольше)
- Обнаружить ошибку проще, потому что она проверяет только одну вещь (но я могу начать писать модульный тест, чтобы проверить каждую отдельную деталь, когда мой интеграционный тест не прошел)
- Найти ошибку, которая может не попасть в интеграционный тест. например, маскирование / устранение ошибок. (но если мои интеграционные тесты пройдут все успешно, это означает, что моя программа будет работать, даже если существует какая-то скрытая ошибка. Поэтому найдите / исправьте эти ошибки не на самом деле с высоким приоритетом, если они не начнут ломать будущие интеграционные тесты или не вызовут проблемы с производительностью)
И мы всегда хотим писать меньше кода, но для написания модульных тестов нужно намного больше кода (в основном это установка фиктивных объектов). Разница между некоторыми из моих модульных тестов и интеграционных тестов заключается в том, что в модульных тестах я использую фиктивный объект, а в интеграционных тестах я использую реальный объект. У которых много дублирования, и мне не нравится дублированный код, даже в тестах, потому что это добавляет накладные расходы для изменения поведения кода (инструмент рефакторинга не может выполнять всю работу все время).
источник
Ответы:
Вы изложили хорошие аргументы за и против юнит-тестирования. Поэтому вы должны спросить себя: « Я вижу ценность в положительных аргументах, которые перевешивают затраты в отрицательных? » Я, конечно, понимаю:
В моей книге плюсы перевешивают минусы.
источник
Я не вижу особой ценности в переосмыслении существующего интеграционного теста в качестве юнит-теста.
Интеграционные тесты часто гораздо проще написать для устаревших приложений, не имеющих ничего общего, потому что обычно тестируемые функциональные возможности тесно связаны, поэтому тестирование отдельных модулей (= тестирование модулей) может быть затруднено / дорого / невозможно.
По моему мнению, разработка на основе тестов наиболее эффективна, если вы пишете модульные тесты перед реальным кодом. Таким образом, код, который выполняет тесты, становится четко разделенным с минимумом внешних ссылок, которые легко тестируются.
Если код уже существует без модульных тестов, то, как правило, требуется много дополнительной работы для написания модульных тестов, потому что код не был написан для простого тестирования.
Если вы делаете TDD, код автоматически легко тестируется.
источник
unit-tests
, и я хочу включитьunit-tests
для определенных частей, как вы думаете, лучше сначала написатьintegration tests
для устаревшего кода. Как только это написано, тогда вы можете отсоединить тесную связь и создать функции с интерфейсами, которые можно протестировать? Поскольку выintegration-test
уже написали, вы можете проверять на каждом этапе рефакторинга, что новая версия кода по-прежнему работает как нужно?Интеграционные тесты должны только проверить, что несколько компонентов работают вместе, как и ожидалось. Точность логики отдельных компонентов должна быть подтверждена модульными тестами.
Большинство методов имеют несколько возможных путей выполнения; Подумайте о if-then-else, входных переменных с неожиданными или просто неправильными значениями и т. д. Обычно разработчики склонны думать только о счастливом пути: нормальном пути, который не идет не так. Но что касается этих других путей, у вас есть два варианта: вы можете позволить своему конечному пользователю исследовать эти пути с помощью действий, которые они выполняют в пользовательском интерфейсе, и надеяться, что они не потерпят крах в вашем приложении, или вы можете написать модульные тесты, которые утверждают поведение этих других путей и принять меры, где это необходимо.
источник
Некоторые из причин, которые вы указали в своем вопросе, действительно важны и сами по себе вполне могут привести аргументы в пользу юнит-тестирования, но YMMV. Например, как часто вы запускаете свой интегрированный набор тестов? Мой опыт работы с интегрированными тестами заключается в том, что рано или поздно они станут такими медленными, что вы не будете запускать их каждый раз, когда вносите изменения, а время между вставкой и обнаружением ошибки увеличивается.
Кроме того, большая ошибка, которую вы можете совершать, заключается в доверии
Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.
не важно. Вы ожидаете, что ваши пользователи найдут ошибки для вас? На мой взгляд, доверять покрытиям, полученным из интегрированных тестов, опасно, вы можете очень легко получить высокий процент охвата, но на самом деле вы тестируете очень мало.
Я полагаю, что канонические ссылки на интегрированные тесты - это посты JBrains:
http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1
в случае, если вы еще не прочитали их.
Наконец, IMO обратная связь, которую вы можете получить от модульных тестов для вашего дизайна, неоценима. Оценка дизайна по внутренним ощущениям и использование интегрированных тестов также могут быть ошибкой.
источник
Если вы ожидаете когда-либо изменить или реорганизовать свой код, проведение модульных тестов имеет важное значение. Модульные тесты существуют не только для демонстрации ошибок во время написания кода, но и для показа, когда появляются новые ошибки, когда пишется больше кода.
Да, гораздо лучше сначала написать свои интеграционные и модульные тесты, но они очень полезны, даже если они будут написаны позже.
источник