Как интеграционные тесты критикуют дизайн?

38

Я прочитал в блоге JB Rainsberger об интегрированных тестах и ​​задаюсь вопросом, каким образом интеграционный тест более суров с нашим дизайном?

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

Alex.U
источник
3
Вопрос запутанный. «Каким образом интеграционные тесты являются более суровыми» ... «Интегрированные тесты, которые больше и не критикуют наш дизайн так резко», - что теперь?
AnoE
"интеграционный тест"! = "интегрированный тест". Я знаю. Мне это тоже не нравится, но вот что означают эти слова. «интеграционные тесты» = «тесты, которые проверяют точки интеграции (без интеграции элементов)», а «интегрированные тесты» = «(более крупные) тесты, которые интегрируют вещи и проверяют интегрированное целое как единое целое». Таким образом, эти термины становятся противоположностями друг друга.
Дж. Б. Рейнсбергер

Ответы:

46

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

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

Обновление : как отмечает Рэйнсбергер ниже, он не хотел, чтобы микротесты были синонимичны с юнит-тестами. Он также предоставил подробный ответ, который может дать вам более глубокое понимание того, о чем он говорил.

Торин Джейкобс
источник
2
Я согласен с вашим ответом в принципе, но не с тем, как вы его формулируете. Тот, кто задает этот конкретный вопрос, вряд ли узнает, что означают термины «издевательство», «связь» и «сплоченность», и вы не определили эти термины в своем ответе.
Роберт Харви
3
Это лучше, но вы даете юнит-тестам больше доверия, чем я думаю, что они на самом деле должны. Модульные тесты в основном сообщают о тестируемости вашего кода. Менее ясно, дает ли ваш тестируемый код автоматически улучшенные характеристики сцепления и сцепления, хотя это, безусловно, оказывает положительное влияние. Кроме того, я думаю, что вас «переплели» перепутали с «принципом единой ответственности»; сплоченность означает «вещи, которые принадлежат друг другу» (см. статью в Википедии ).
Роберт Харви
10
Наконец, «микро-тесты» не является предпочтительным термином. Мне нравится, когда блогеры создают свои собственные технические термины.
Роберт Харви
2
@RubberDuck: Микротесты (около 16 900 результатов) против юнит-тестов (около 193 000 000 результатов) . Даже не близко. Даже если вы станете мастером и будете тестировать вместе, вы все равно получите 14 миллионов результатов.
Роберт Харви
5
Пожалуйста, не приравнивайте «микротест» и «модульный тест» (см. Мой ответ для некоторых деталей); иначе я чувствую, что вы поняли, что я пытался описать.
Дж. Б. Рейнсбергер
28

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

Во-первых, чтобы уточнить, когда я говорю «микротест», я имею в виду «маленький тест» и ничего более. Я использую этот термин, потому что я не имею в виду «модульный тест»: я не хочу втягиваться в дебаты о том, что составляет «юнит». Мне все равно (по крайней мере, не здесь / сейчас). Два человека, вероятно, с большей легкостью согласятся на «маленький», чем на «единицу», поэтому я постепенно решил принять «микротест» в качестве нового стандартного термина для этой идеи.

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

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

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

Дж. Б. Рейнсбергер
источник
Что вы делаете с проблемой, когда модульные тесты больше полагаются на их макеты, чем на реальный код, что приводит к проблеме тестов, которые, кажется, проходят, но на самом деле не работают, потому что никто не поддерживал макеты в соответствии с реальностью.
Zan Lynx
@ZanLynx Я написал об этом подробно. Начните здесь: blog.thecodewhisperer.com/series#integrated-tests-are-a-scam
Дж. Б. Рейнсбергер,
9

Он имеет в виду, что хороший дизайн программного обеспечения лучше информирован модульными тестами, чем интеграционными.

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

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

Роберт Харви
источник