анти-паттерн : должно быть по крайней мере два ключевых элемента, чтобы формально отличить реальный анти-паттерн от простой вредной привычки, плохой практики или плохой идеи:
- Некоторая повторяющаяся модель действий, процессов или структур, которая первоначально кажется полезной, но в конечном итоге приводит к более плохим последствиям, чем полезные результаты, и
- Реорганизованное решение, которое четко документировано, проверено на практике и воспроизводимо.
Голосуйте за анти-паттерн TDD, который вы видели «в дикой природе» один раз слишком много.
Сообщение в блоге Джеймса Карра и смежное обсуждение testdrivendevelopment yahoogroup
Если вы нашли "неназванный" один .. опубликовать их тоже. Один пост за антишаблон, пожалуйста, чтобы голоса подсчитывали.
Мой личный интерес состоит в том, чтобы найти подмножество top-n, чтобы я мог обсудить их в ближайшем будущем на ланч-боксе.
unit-testing
tdd
anti-patterns
Gishu
источник
источник
Ответы:
Граждане второго класса - тестовый код не так хорошо подвергнут рефакторингу, как производственный код, содержащий много дублирующегося кода, что затрудняет сопровождение тестов.
источник
Free Ride / Piggyback - Джеймс Карр, Тим Оттингер
Вместо того, чтобы писать новый метод контрольного примера, чтобы проверить другую / отличную особенность / функциональность , новое утверждение (и его соответствующие действия, то есть шаги действия от AAA) продвигается в существующем контрольном примере ,
источник
true
после каждого возможного вызова мутатора. Таким образом, вы захотите проверить, что каждый инвариант находитсяtrue
после каждой комбинации мутатора и входных данных, которые вы тестируете. Но вы захотите уменьшить дублирование и убедиться, что вы проверяете все инварианты, включая те, которые в настоящее время не вызывают сбоев теста. Таким образом, вы помещаете их все в функциюcheckInvariants()
проверки и используете это в каждом тесте. Код изменяется и добавляется еще один инвариант. Вы, конечно, тоже включили это в функцию. Но это фрирайдер.Счастливый путь
Тест остается на удачных путях (то есть ожидаемых результатах) без проверки границ и исключений.
Юнит Антипаттерны
источник
Местный герой
Тестовый пример, который зависит от чего-то определенного для среды разработки, на которой он был написан для запуска. В результате тест проходит на блоках разработки, но не проходит, когда кто-то пытается запустить его в другом месте.
Скрытая зависимость
Тесно связанный с местным героем, модульный тест, который требует, чтобы некоторые существующие данные были заполнены где-то до запуска теста. Если эти данные не были заполнены, тест завершится неудачей и оставит разработчику мало информации о том, что он хочет или почему ... заставит их копаться в акрах кода, чтобы выяснить, откуда должны были использоваться данные, которые он использовал.
К сожалению, слишком много раз это происходило с древними .dll, которые зависят от туманных и разнообразных файлов .ini, которые постоянно не синхронизированы в какой-либо конкретной производственной системе, не говоря уже о существовании на вашем компьютере без подробных консультаций с тремя разработчиками, ответственными за эти библиотеки. Вздох.
источник
Цепная банда
Пара тестов, которые должны выполняться в определенном порядке, то есть один тест изменяет глобальное состояние системы (глобальные переменные, данные в базе данных), и от него зависит следующий тест (ы).
Вы часто видите это в тестах базы данных. Вместо отката
teardown()
тесты фиксируют свои изменения в базе данных. Другая распространенная причина заключается в том, что изменения глобального состояния не заключаются в блоки try / finally, которые очищаются при сбое теста.источник
Издевательство
Иногда издевательство может быть хорошим и удобным. Но иногда разработчики могут потерять себя и в своих попытках высказать то, что не тестируется. В этом случае модульное тестирование содержит так много макетов, заглушек и / или подделок, что тестируемая система вообще даже не тестируется, вместо этого тестируются данные, возвращаемые из макетов.
Источник: сообщение Джеймса Карра.
источник
Тихий Ловец - Келли?
Тест, который проходит, если выбрасывается исключение ... даже если фактически возникает исключение, отличное от того, которое разработчик намеревался.
Смотрите также: Secret Catcher
источник
Инспектор
Модульный тест, который нарушает инкапсуляцию в попытке достичь 100% покрытия кода, но знает так много о том, что происходит в объекте, что любая попытка рефакторинга нарушит существующий тест и потребует, чтобы любые изменения были отражены в модуле. тест.
'Как мне проверить мои переменные-члены, не делая их общедоступными ... только для модульного тестирования?'
источник
Чрезмерная настройка - Джеймс Карр
Тест, требующий огромной настройки, чтобы даже начать тестирование. Иногда несколько сотен строк кода используются для подготовки среды к одному тесту с участием нескольких объектов, что может затруднить определение того, что тестируется, из-за «шума» всех происходящих настроек. (Src: сообщение Джеймса Карра )
источник
Анальный Зонд
Тест, который должен использовать безумные, незаконные или иные нездоровые способы выполнения своей задачи, такие как: чтение приватных полей с использованием Java setAccessible (true) или расширение класса для доступа к защищенным полям / методам или необходимость помещать тест в определенный пакет для доступа Пакет глобальных полей / методов.
Если вы видите этот шаблон, тестируемые классы используют слишком много скрытых данных.
Разница между этим и Инспектором заключается в том, что тестируемый класс пытается скрыть даже то, что вам нужно проверить. Таким образом, ваша цель состоит не в том, чтобы достичь 100% тестового покрытия, а в том, чтобы вообще что-либо тестировать. Подумайте о классе, который имеет только закрытые поля, о
run()
методе без аргументов и вообще не о методах получения. Нет способа проверить это без нарушения правил.Комментарий Майкла Боргвардта: Это на самом деле не тестовый антипаттерн, это прагматизм для устранения недостатков в тестируемом коде. Конечно, эти недостатки лучше исправить, но это может быть невозможно в случае сторонних библиотек.
Аарон Дигулла: Я вроде согласен. Может быть, эта статья действительно лучше подходит для вики "JUnit HOWTO", а не для antipattern. Комментарии?
источник
Тест без имени - Ник Пеллоу
Тест, добавляемый для воспроизведения конкретной ошибки в трекере ошибок, автор которой считает, что не требует собственного имени. Вместо улучшения существующего, испытывающего недостаток теста, создается новый тест под названием testForBUG123.
Два года спустя, когда этот тест не пройден, вам, возможно, придется сначала попытаться найти BUG-123 в вашем баг-трекере, чтобы выяснить цель теста.
источник
Медленная тычка
Модульный тест, который работает невероятно медленно. Когда разработчики начинают его, у них есть время пойти в ванную, покурить или, что еще хуже, начать тестирование, прежде чем они вернутся домой в конце дня. (Src: сообщение Джеймса Карра )
так называемые тесты, которые не запускаются так часто, как следовало бы
источник
Бабочка
Вы должны протестировать что-то, что содержит данные, которые постоянно изменяются, например, структуру, которая содержит текущую дату, и нет никакого способа закрепить результат до фиксированного значения. Некрасивая часть заключается в том, что вам не важно это значение. Это только делает ваш тест более сложным, не добавляя никакой ценности.
Летучая мышь его крыла может вызвать ураган на другом конце света. - Эдвард Лоренц, Эффект бабочки
источник
System.DateTime.Now
, помимо того , что более простые или более детерминированные модульные тесты?toString()
объекта, который не перезаписывает метод. Это даст вам идентификатор объекта, который зависит от адреса памяти. ИлиtoString()
содержит первичный ключ объекта, который изменяется при каждом запуске теста. Есть три способа исправить это: 1. изменить код, который вы тестируете, 2. использовать regexp для удаления переменных частей результатов теста или 3. использовать мощные инструменты для перезаписи системных служб, чтобы они возвращали предсказуемые результаты.Мерцающий тест (Источник: Ромилли Кокс)
Тест, который просто иногда не проходит, а не в определенное время, и, как правило, обусловлен условиями гонки в рамках теста. Обычно происходит при тестировании чего-то асинхронного, такого как JMS.
Возможно, супер-набор для анти-паттерна « Жди и смотри » и анти-паттерна «Спящий ».
Сборка не удалась, ну ладно, просто запустите сборку снова. - анонимный разработчик
источник
Ждать и смотреть
Тест, который запускает некоторый настроенный код, а затем должен «подождать» определенное количество времени, прежде чем он сможет «увидеть», работает ли тестируемый код как ожидалось. TestMethod, который использует Thread.sleep () или эквивалентный, - это, безусловно, тест «Жди и смотри».
Как правило, вы можете увидеть это, если тест тестирует код, который генерирует внешнее по отношению к системе событие, такое как электронная почта, запрос http или записывает файл на диск.
Такой тест также может быть локальным героем, так как он не пройдёт при запуске на более медленном боксе или перегруженном CI-сервере.
Анти-паттерн «Жди и смотри» не следует путать со спящим .
источник
Неправильно
расшаренный прибор - Тим Оттингер. Несколько тестовых случаев в тестовом приборе даже не используют или не требуют настройки / демонтажа. Частично из-за инерции разработчика, чтобы создать новое тестовое оборудование ... проще просто добавить еще один тестовый набор в кучу
источник
Гигант
Модульное тестирование, которое, хотя и является действительным тестированием тестируемого объекта, может занимать тысячи строк и содержать множество тестовых случаев. Это может быть индикатором того, что тестируемая система является объектом Бога (пост Джеймса Карра).
Безусловным признаком этого является тест, который занимает несколько строк кода. Часто тест настолько сложен, что начинает содержать ошибки своего или нестабильного поведения.
источник
Я поверю в это, когда увижу несколько вспыхивающих графических интерфейсов
. Нездоровая фиксация / одержимость тестированием приложения через графический интерфейс «точно так же, как настоящий пользователь»
«Вы должны понимать, что видеть - значит верить, но также знать, что верить - это видеть». - Денис Уэйтли
источник
Спящий, он же Везувий - Ник Пеллоу
Тест, который предназначен для неудачи в определенное время и в будущем. Это часто вызвано неправильной проверкой границ при тестировании кода, который использует объект Date или Calendar. Иногда тест может не пройти, если он выполняется в очень определенное время суток, например в полночь.
«Спящего» не следует путать с анти-паттерном « Жди и смотри ».
Этот код будет заменен задолго до 2000 года - многие разработчики в 1960 году
источник
Мертвое дерево
Тест, в котором была создана заглушка, но на самом деле тест не был написан.
Я действительно видел это в нашем производственном коде:
Я даже не знаю, что об этом думать.
источник
получил немного этим сегодня:
Мокрый пол :
тест создает данные, которые сохраняются где-то, но тест не очищается после завершения. Это приводит к сбою тестов (того же теста или, возможно, других тестов) при последующих тестовых прогонах.
В нашем случае тест оставил файл в папке «temp» с разрешениями пользователя, который запустил тест в первый раз. Когда другой пользователь пытался провести тестирование на той же машине: boom. В комментариях на сайте Джеймса Карра Йоаким Олрогге назвал это «небрежным рабочим», и это было частью вдохновения для «Щедрых остатков». Мне нравится мое имя лучше (менее оскорбительно, более знакомо).
источник
Кукушка - Фрэнк Карвер
. Модульное тестирование, которое проходит в тестовом наборе с несколькими другими и использует тот же (потенциально длительный) процесс настройки, что и другие тесты в тестовом примере, но затем отбрасывает некоторые или все артефакты из установки и создает свое.
Расширенный Симптом: ненадлежащим образом совместное приспособление
источник
The Secret Catcher - Фрэнк Карвер
Тест, который на первый взгляд кажется не проводящим тестов из-за отсутствия утверждений. Но «Дьявол кроется в деталях»… тест действительно полагается на исключение, которое будет выдано, и ожидает, что среда тестирования перехватит исключение и сообщит о нем пользователю как об ошибке.
источник
Assert.DoesNotThrow(SomeDelegateType act)
утверждение стиля, которое можно использовать специально в подобных случаях. Я нахожу это менее грубым, чем тестовый пример, который завершается успешно, когда конструктор возвращает ненулевое значение, но завершается неудачей, когда конструктор генерирует ошибку. Конструктор никогда не вернет ноль. (Примечание: применяется только к языкам, где конструктор гарантированно возвращает ненулевое значение)Экологический вандал
«Модульный» тест, который для различных «требований» начинает распространяться в его среду, используя и устанавливая переменные / порты среды. Запуск двух из этих тестов одновременно вызовет исключения «недоступный порт» и т. Д.
Эти тесты будут прерывистыми, и разработчики будут говорить что-то вроде «просто запустите его снова».
Я видел одно решение - случайно выбрать номер порта для использования. Это уменьшает вероятность конфликта, но явно не решает проблему. Поэтому, если вы можете, всегда смоделируйте код, чтобы он фактически не выделял неразделимый ресурс.
источник
Тест Тьюринга
Тестовый сценарий, автоматически сгенерированный каким-то дорогим инструментом, который имеет много-много утверждений, полученных из тестируемого класса с использованием слишком сложного анализа потока данных. Приводит разработчиков в ложное чувство уверенности в том, что их код хорошо протестирован, освобождая их от ответственности за разработку и поддержание высококачественных тестов. Если машина может написать тесты для вас, почему она не может вынуть свой палец и написать само приложение!
Привет глупый. - Самый умный компьютер в мире для нового ученика (от старого комикса Amiga).
источник
Сорок полюсных испытаний
Опасаясь оказаться слишком близко к классу, который они пытаются протестировать, эти тесты действуют на расстоянии, отделенном бесчисленными слоями абстракции и тысячами строк кода от проверяемой ими логики. Как таковые, они чрезвычайно хрупкие и подвержены всевозможным побочным эффектам, которые происходят в эпическом путешествии к классу интересов и обратно.
источник
Doppelgänger
Чтобы что-то протестировать, вы должны скопировать части тестируемого кода в новый класс с тем же именем и пакетом, а также использовать магию пути к классам или пользовательский загрузчик классов, чтобы убедиться, что он виден первым (поэтому ваша копия выбрана) вверх).
Этот шаблон указывает на нездоровое количество скрытых зависимостей, которые вы не можете контролировать из теста.
Я посмотрел на его лицо ... мое лицо! Это было похоже на зеркало, но заставило мою кровь замерзнуть.
источник
Курица-мать - Фрэнк Карвер
Обычная установка, которая делает гораздо больше, чем нужно для реальных тестовых случаев. Например, создание всевозможных сложных структур данных, заполненных, по-видимому, важными и уникальными значениями, когда в тестах утверждается только наличие или отсутствие чего-либо.
Расширенный Симптом: ненадлежащим образом совместное приспособление
Я не знаю, что это делает ... Я все равно добавляю это, на всякий случай. - анонимный разработчик
источник
Тест это все
Я не могу поверить, что это не упоминалось до сих пор, но тесты не должны нарушать принцип единой ответственности .
Я сталкивался с этим много раз, и тесты, нарушающие это правило, по определению являются кошмаром.
источник
Линия нападающий
На первый взгляд, тесты охватывают все, и инструменты покрытия кода подтверждают это на 100%, но в действительности тесты проверяют только код без какого-либо анализа выходных данных.
Покрытие-против-достижимости-кода
источник