Что означает «DAMP not DRY», говоря о модульных тестах?


345

Я слышал, как кто-то сказал, что юнит-тесты (например, nUnit, jUnit, xUnit) должны быть

DAMP не сухой

(Например, модульные тесты должны содержать «влажный код», а не «сухой код»)

О чем они говорят?


2
В модульных тестах нет ничего особенного, что оправдывает неСУХОЙ код. Написание неСУХОГО теста - это оправдание ленивым программистам пытаться вырезать территорию для своей лени. Проще говоря, СУХОСТЬ и удобочитаемость являются ортогональными проблемами.
Acumenus

2
СУХОСТЬ увеличивает дистанцию ​​навигации по коду, что, в свою очередь, приводит к большей умственной нагрузке для понимания. Это верно в «нормальной» текстовой среде. Проекционный редактор может снизить ортогональность кода, но не в каждом случае.
Питер

Я рекомендую эту статью: enterprisecraftsmanship.com/posts/dry-damp-unit-tests
Владимир

Ответы:


596

Это баланс, а не противоречие

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

DAMP (Описательные и осмысленные фразы) способствует удобочитаемости кода.

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

СУХОЙ (не повторяйте себя) продвигает ортогональность кода.

Удаление дублирования гарантирует, что каждая концепция в системе имеет единственное авторитетное представление в коде. Изменение единой бизнес-концепции приводит к единственному изменению кода. СУХОЙ повышает ремонтопригодность, изолируя изменения (риск) только для тех частей системы, которые должны измениться.

Итак, почему дублирование более приемлемо в тестах?

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

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

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

Как правило, поддерживайте DRY в рабочем коде, поддерживайте DAMP в тестовом коде. Хотя оба одинаково важны, с небольшой мудростью вы можете изменить баланс в свою пользу.


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

3
@ Джейсон, кстати, есть ли ссылка на «Джеспер Ландберг также имеет хороший трактат на эту тему» ?
Pacerier

2
@JohnSaunders, вы можете избежать такого дублирования, используя шаблон построителя тестовых данных: natpryce.com/articles/000714.html
si618

2
ВЫКЛЮЧЕНИЕ тестового кода может создать
скрытый

1
Я также добавил бы, что хорошо написанные тесты - это, по сути, документация / комментарии для вашего приложения. Таким образом, более наглядный помогает объяснить ваши намерения другим разработчикам. И как говорит OP, они самодостаточны в каждом тесте, поэтому опасность для вашего приложения минимальна. В худшем случае у вас есть избыточный тест или настройка теста, и для запуска набора тестов требуется больше времени. Я предпочел бы ошибиться на стороне хорошего тестового покрытия.
Ли Макалли

60

DAMP - Описательные и осмысленные фразы.

«DAMP not DRY» значения читаемости по сравнению с повторным использованием кода. Идея DAMP, а не DRY в тестовых случаях заключается в том, что тесты должны быть простыми для понимания, даже если это означает, что тестовые примеры иногда повторяют код.

См. Также Является ли дублированный код более приемлемым в модульных тестах? для некоторого обсуждения достоинств этой точки зрения.

Возможно, это было придумано Джеем Филдсом по отношению к предметно-ориентированным языкам.


1
Хороший ответ и ссылка на связанный вопрос. Не существует идеального DAMP против DRY выбора. Мы хотим, чтобы код был максимально сухим, а при тестировании - не настолько сухим, чтобы его было трудно понять. Когда тест не пройден, я хочу, чтобы причина была очевидной, чтобы разработчик мог приступить к исправлению SUT, что означает, что я склоняюсь к DAMP-коду в тестах. Как и большинство концепций программирования, всегда можно зайти слишком далеко. Если ваш код модульного теста настолько сухой, что требуется много времени, чтобы определить, как и почему тест не прошел, он может быть «слишком сухим».
Джеральд Дэвис,

29

«СУХОЙ» - «Не повторяйся»

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

«DAMP» - это «Описательные и значимые фразы».

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


15
AIUI, DRY - это не только вопрос экономии времени за счет повторного использования, но и предотвращение «несинхронизации» различных путей кода. Если вы копируете и вставляете одну и ту же логику в несколько классов, каждый экземпляр этого кода необходимо будет обновить, когда потребуется изменение. (И неизбежно один из них не будет, и взорвется, когда осуществлен.)
Анджей Дойл

20

Damp = «Описательные и осмысленные фразы» - ваши юнит-тесты должны быть «прочитаны»:

Читаемость важнее, чем избегать избыточного кода.

Из статьи:

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

Что это значит и где его использовать?

DAMP в основном применяется при написании тестового кода. Тестовый код должен быть очень простым для понимания до такой степени, что некоторая избыточность является приемлемой.


11

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

http://codeshelter.wordpress.com/2011/04/07/dry-and-damp-principles-when-developing-and-unit-testing/


11

Здесь уже есть несколько ответов, но я хотел добавить еще один, так как не думал, что они обязательно объяснят это так хорошо, как могли.

Идея СУХОГО (не повторяйте себя) заключается в том, что в коде вашего приложения вы хотите избежать избыточного или повторяющегося кода. Если у вас есть что-то, что ваш код должен делать несколько раз, у вас должна быть функция или класс, а не повторять аналогичный код в нескольких местах.

Это довольно известная концепция программирования.

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

например: testWhenIAddOneAndOneIShouldGetTwo() { .... }

Когда вы читаете имя метода DAMP, как это, вы должны точно понимать, что автор теста пытался достичь, даже не читая тестовый код (хотя тестовый код также может следовать этой концепции, конечно же, с многословными именами переменных, и т.д).

Это возможно, потому что метод модульного тестирования имеет очень специфический вход и ожидаемый результат, поэтому принцип DAMP хорошо работает для них. Методы в вашем основном коде приложения вряд ли будут достаточно конкретными, чтобы оправдывать подобные имена, особенно если вы написали его с учетом принципа СУХОЙ.

DAMP и DRY не противоречат друг другу - они охватывают различные аспекты написания вашего кода - но, тем не менее, они обычно не используются вместе, поскольку методы, написанные с учетом принципа DRY, будут универсальными и вряд ли подойдут к очень конкретному названию метода. В общем, поэтому, как объяснено выше, код вашего приложения должен быть СУХИМЫМ, а код модульного тестирования - DAMP.

Я надеюсь, что это поможет объяснить это немного лучше.


5

Я согласен с Крисом Эдвардсом в том, что вам нужно найти баланс между ними. Еще одна вещь, на которую следует обратить внимание: если вы пытаетесь удалить дублирование, в конечном итоге добавляете много дополнительной структуры в код модульного теста (т. Е. Когда DRY доводится до крайности), вы рискуете ввести в нее ошибки. В такой ситуации вам придется либо выполнить модульное тестирование своих модульных тестов, либо оставить биты структуры непроверенными.


0

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

Я написал в блоге о DRY против DAMP, который включает в себя несколько примеров.

Ни один из подходов не должен быть вашим единственным решением, иногда DAMP является излишним, а иногда очень хорошим дополнением.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.