Что не следует тестировать, когда дело доходит до модульного тестирования?

StackOverflow https://stackoverflow.com/questions/109432

Вопрос

В каких частях проекта написание модульных тестов практически или вообще невозможно?Доступ к данным?фтп?

Если на этот вопрос есть ответ, то 100% покрытие – это миф, не так ли?

Это было полезно?

Решение

Здесь Я нашел (через взломан что-то, что говорит Майкл Фезерс, может быть ответом:

Он говорит,

Тест не является модульным тестом, если:

  • Он общается с базой данных
  • Он общается по сети
  • Это касается файловой системы
  • Он не может работать одновременно с любым другим модульным тестом.
  • Для его запуска вам придется выполнить особые действия в вашей среде (например, отредактировать файлы конфигурации).

И снова в той же статье он добавляет:

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

Другие советы

То, что 100-процентный охват — это миф, но это не означает, что 80-процентный охват бесполезен.Цель, конечно, 100%, и между юнит-тестами, а затем интеграционными тестами можно к ней приблизиться.

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

достижение 100% покрытия кода почти всегда является расточительным.Есть много ресурсов по этому поводу.

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

Целью является не 100-процентное покрытие кода и не 80-процентное покрытие кода.Легкость написания модульного теста не означает, что вы должны его писать, а сложность написания модульных тестов не означает, что вам следует избегать усилий.

Целью любого теста является обнаружение видимых пользователем проблем наиболее доступным способом.

Стоит ли общая стоимость создания, поддержки и диагностики проблем, отмеченных тестом (включая ложные срабатывания), тех проблем, которые выявляет конкретный тест?

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

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

Что бы вы не тестировали?Все, что невозможно сломать.

Когда дело доходит до покрытия кода, вы хотите стремиться к 100% кода, который вы на самом деле пишете - то есть вам не нужно тестировать код сторонней библиотеки или код операционной системы, поскольку этот код будет доставлен вам для тестирования.Если только это не так.В этом случае вы можете проверить это.Или, если есть известные ошибки, в этом случае вы можете проверить наличие ошибок, чтобы получить уведомление о том, когда они будут исправлены.

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

Доступ к данным возможен, поскольку вы можете настроить тестовую базу данных.

Обычно «непроверяемые» вещи — это FTP, электронная почта и т. д.Однако, как правило, это классы фреймворка, на которые можно положиться, и поэтому их не нужно тестировать, если вы скрываете их за абстракцией.

Кроме того, 100% покрытия кода само по себе недостаточно.

@ГарриШатлер

На самом деле я проверяю электронную почту, используя поддельный SMTP-сервер (Wiser).Проверяет правильность кода приложения:

http://maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/

Что-то подобное, вероятно, можно было бы сделать и для других серверов.В противном случае вы сможете издеваться над API...

КСТАТИ:100% покрытие - это только начало...просто означает, что весь код фактически выполнен один раз....ничего о крайних случаях и т. д.

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

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

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

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

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

При модульном тестировании вы не должны тестировать ничего, что не принадлежит вашему модулю;тестирование единиц в их контексте – это другое дело.Это простой ответ.

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

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

"Что не протестировать, когда дело доходит до модульного тестирования?" * Бобы с просто Getters и Setters.Аргументация:Обычно это пустая трата времени, которое лучше потратить на тестирование чего-то другого.

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

Тем не менее, модульные тесты не должны быть единственным уровнем тестирования вашего приложения.Достижение 100%-ного покрытия модульными тестами часто является пустой тратой времени, а отдача от нее быстро снижается.

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

Все, что требует очень большой и сложной настройки.Конечно, вы можете протестировать ftp (клиент), но тогда вам нужно настроить ftp-сервер.Для модульного тестирования вам нужна воспроизводимая тестовая установка.Если вы не можете его предоставить, вы не можете его протестировать.

Вы можете протестировать их, но это не будут модульные тесты.Модульное тестирование — это то, что не переходит границ, например, пересечение проводов, обращение к базе данных, запуск/взаимодействие с третьей стороной, касание непроверенной/устаревшей кодовой базы и т. д.

Все, что выходит за рамки этого, является интеграционным тестированием.

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

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

Конечно, 100% охват — это хорошо. цель при работе над большим проектом, но для большинства проектов исправление одной или двух ошибок перед развертыванием не обязательно стоит времени на создание исчерпывающих модульных тестов.

Исчерпывающее тестирование таких вещей, как отправка форм, доступ к базе данных, доступ по FTP и т. д. на очень детальном уровне часто является пустой тратой времени;если только для написанного программного обеспечения не требуется очень высокий уровень надежности (99,999%), слишком много модульного тестирования может быть излишним и тратить время в реальном времени.

Я не согласен с ответом Quamrana относительно отказа от тестирования стороннего кода.Это идеальное использование модульного теста.Что, если ошибки появятся в новой версии библиотеки?В идеале, когда выпускается новая версия сторонней библиотеки, вы запускаете модульные тесты, которые отражают ожидаемое поведение этой библиотеки, чтобы убедиться, что она по-прежнему работает должным образом.

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

FTP, SMTP, ввод-вывод в целом следует тестировать с использованием интерфейса.Интерфейс должен быть реализован с помощью адаптера (для реального кода) и макета для модульного теста.

Ни один модульный тест не должен использовать реальный внешний ресурс (FTP-сервер и т. д.).

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

FTP, электронная почта и т. д. можно протестировать с помощью эмуляции сервера.Это сложно, но возможно.

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

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

Основная причина использования кода модульного тестирования — это проверка дизайна вашего кода.Можно добиться 100% покрытия кода, но не без использования фиктивных объектов или какой-либо формы изоляции или внедрения зависимостей.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top