Тип проектов, где модульное тестирование бесполезно

Считаете ли вы, что модульное тестирование (и разработка, основанное на тестах) должно выполняться при любых обстоятельствах или при наличии некоторых исключений. В последнее время я работаю над типом проектов, где я не вижу, как модульное тестирование будет полезно или улучшит дизайн, качество кода и т.д. Один тип проекта - это генератор отчетов PDF, который принимает агрегированные данные (значения уже рассчитаны и QAed) и выводит его в файл отчета PDF. Другим типом являются прямолинейные CRUD-приложения, использующие сторонний инструмент ORM. Я могу понять, как кто-то может принять аргумент в пользу использования Unit Testing для CRUD-приложения, но это требует много ненужной и трудоемкой работы по настройке, например, выбивает все вызовы в базу данных и насмешливые бизнес-объекты и т.д., Когда в конце все вам нужно знать, произошло ли что-то с БД. Итак, когда нужно использовать или избегать модульного тестирования?

Спасибо

Ответ 1

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

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

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

Ответ 2

Пожалуйста, не связывайте модульное тестирование (UT), которое является инструментом, с тестовым дизайном (TDD), который является методологией. подробнее об этом

Кроме того, помните, что одним из преимуществ модульных тестов является регрессионное тестирование, то есть как страхование от будущих изменений (и чтобы убедиться, что исправленные ошибки не становятся неустановленными).

В вашем первом примере я бы выполнил модульное тестирование преобразования PDF следующим образом:

  • начните с известного набора выборочных данных и создайте документ PDF
  • вручную проверьте правильность созданного PDF
  • сохранить образцы данных и исправить PDF-документ как часть набора тестов
  • напишите функцию для сравнения двух документов PDF для различий (на уровне двоичных файлов или контента)
  • автоматизировать этот unit test, чтобы сравнить PDF-документ, сгенерированный из данных образца, с подтвержденным документом с первого шага.

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

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

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

В вашем втором примере это звучит так, будто вы будете тестировать сторонний инструмент ORM, что, вероятно, бессмысленно. Однако опять-таки некоторые базовые тесты могут быть полезны в качестве страхования от будущих изменений в зависимости от того, как вы используете этот инструмент. Например, вместо того, чтобы издеваться над всей цепочкой n-уровня (я не поклонник насмешек, когда это не обязательно), просто используйте инструмент ORM для создания, чтения, обновления и удаления типичного объекта/записи и проверьте операцию, используя прямые SQL-запросы в базе данных (test). Таким образом, если сторонний поставщик позже обновит что-то, что нарушит основные функции, о которых вы узнаете, а новые разработчики в вашем проекте могут легко увидеть, как использовать инструмент ORM из примеров unit test.

Ответ 3

Я никогда не сталкивался с стратегией для модульного тестирования уровня представления приложения, которое стоило проблем.

Мне бы очень хотелось, чтобы кто-то доказал это неправильно.

Ответ 4

Перефразируя недавние комментарии Джеффа и Джоэла к SOB: вы должны выполнить модульное тестирование, когда оно добавит ценность вашему продукту.

В двух случаях, которые вы описываете, вы могли бы выполнить ВСЕ ОПИСАНИЕ специальных исправлений (и/или пост-факто регрессионное тестирование) по той же цене, что и тесты на блок-станцию. Поэтому не записывайте модульные тесты.

Ответ 5

"... это много ненужных и трудоемких работ по настройке, таких как выбивание всех вызовов в базу данных и насмешливые бизнес-объекты и т.д., когда в конце все, что вам нужно знать, что-то случилось с БД."

Похоже, вы тестируете неправильную вещь.

Зачем заглушать вызовы базы данных? Почему бы не создать тестовую базу данных и проверить фактические вызовы базы данных в отношении этой тестовой базы данных? [Это то, как работает тестовый сервер Django, и это здорово.]

Почему издеваются над бизнес-объектами? Это то, что вы тестируете, не так ли? Хорошо сказать "мы предполагаем, что работа ORM" и объявить ваш "блок" - это бизнес-объект + база данных ORM+. Испытайте, что, поскольку это возникает вопрос.

Unit test то, что вы написали.

То, что вы загрузили, должно иметь свои собственные модульные тесты.

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

Ответ 6

Я думаю, вам следует избегать модульного тестирования проектов, где код не должен работать.

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

Ответ 7

"Я когда-то слышал, как кто-то сказал, что если он пишет более 10 строк кода без тестов, то он начинает сомневаться, что код, который он только что написал, будет работать правильно".

Этот человек представляет опасность для себя. Немедленно удалите их из кода.

Ответ 8

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

Если вы обнаружите, что пишете полезные модульные тесты, ваша работа, вероятно, не является чем-то обычным:)

EDIT: Напротив, интеграционные тесты обычно очень полезны, но гораздо сложнее автоматизировать затем модульные тесты.

Ответ 9

Чтобы ответить на ваш вопрос, есть определенные исключения.

Фактически, я бы сказал, что полезность автоматического тестирования белого ящика скорее скорее исключение, чем правило.

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

Уайт-бокс с автоматическими тестами был инструментом в инструменте на какое-то время - в последнее время по какой-то причине все это ярость, и если вы высказываетесь против этого, вы подвергаетесь остракизму до степени фанатиками TDD.

Лучше понять это и использовать его там, где это может быть полезно. Например, мой друг был SDET в команде Microsoft Frarmework - это был пример gerat, где TDD был отличным активом. То есть они разрабатывали двигатель для среды разработки, который будет использоваться миллионами людей.

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

Ответ 10

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

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

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

В примере CRUD вы не закрываете сторонний инструмент ORM. Вы пишете обертку вокруг нее, потому что в ближайшие 2 года инструмент ORM либо будет заменен чем-то более ярким, либо просто получит некоторое несовместимое с BC обновление. Затем вы пишете тесты интеграции с полной загрузкой специально для этой оболочки, чтобы убедиться, что она делает то, что требуется вашему приложению, а затем издеваться над оболочкой во всех других тестах, чтобы они не зависели от среды выполнения. Оба этих типа тестов имеют решающее значение для предотвращения регрессий и поддержки в процессе рефакторинга.

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

Ответ 11

  • Например, автоматические тесты для уровня пользовательского интерфейса/презентации часто не стоят проблем. В этом случае часто лучше всего поддерживать слой презентации очень тонким и иметь тестируемый слой, который содержит все функциональные возможности уровня представления. Затем слой презентации будет в основном декларативным и содержать только простой код клея. Когда все декларативно, мало что может сломаться, поэтому тестирование не нужно. Вещи, такие как элементы пользовательского интерфейса, выровненные правильно, - это макет ok, правильные метки и т.д. Легче проверить вручную.

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

Ответ 12

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

Ответ 13

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

Ответ 14

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

Если я хочу протестировать эту функциональность, мне нужно создать симулятор, который имитирует поведение машины, чтобы выполнить некоторые тесты черного ящика в этом классе. Построение симулятора, вероятно, займет не менее 50% времени, необходимого мне для коммуникатора.

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

Ответ 15

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

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

Ответ 16

Unit Test может быть частью процесса QA, но это не должен быть весь процесс QA.

В общем случае Unit test используется как:

a) некоторые QA использует только Unit test, и эти процессы обычно пропускают много проблем, которые не могут быть протестированы автоматически. Например (и это не так странно), ленивые ребята QA, которые спрашивают готовый Unit test, тогда они могут вводить некоторые значения и называть его днем.

b) Другое QA используется как дополнение к другому тесту. Тем не менее, я тенденции (всегда?) Должны быть избыточными.

Таким образом, если Unit test не является безболезненным (специально для того, чтобы не добавлять или изменять код), то тестирование старой школы - это решение (в любом случае, ручное тестирование должно быть выполнено).