Важны ли макеты фреймворков и высокий уровень тестового покрытия?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

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

Уважаемые SOers, что вы думаете по этому поводу?

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

Решение

Это зависит от того, как вы моделируете домен (ы) вашей программы.

Если вы моделируете домены с точки зрения данных, хранящихся в структурах данных и методах, которые считывают данные из одной структуры данных и хранят производные данные в другой структуре данных (процедуры или функции зависят от того, насколько процедурным или функциональным является ваш проект), то имитируйте объекты не подходят. Так называемый «основанный на состоянии» тестирование это то, что вы хотите. Результат, который вас волнует, заключается в том, что процедура помещает правильные данные в правильные переменные, и то, что она вызывает, чтобы это произошло, является лишь деталями реализации.

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

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

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

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

Я прочитал 2 вопроса:

Что вы думаете о проверке того, что определенные методы для компонентов вызываются в определенном порядке?

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

Тесты, которые проверяют только одну вещь, легче понять и поддерживать.

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

Нужно ли быть одержимым тестовым освещением?

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

Общая статистика покрытия модульных тестов? Не особенно интересно, пока они высокие.

100% покрытие модульных тестов для всей системы? Совсем не интересно.

Я согласен - я склоняюсь к тому, чтобы склоняться к проверке состояния, а не к проверке поведения (слабая интерпретация nofollow noreferrer "> классическая TDD , в то же время все еще используя тестовые двойники).

В книге Искусство модульного тестирования есть много полезных советов в этих областях.

100% охват тестированием, тестирование GUI, тестирование геттеров / сеттеров или другого нелогичного кода и т. д. вряд ли обеспечат хорошую рентабельность инвестиций. В любом случае TDD обеспечит высокое тестовое покрытие. Проверьте, что может сломаться.

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

  1. Какова вероятность того, что во время обслуживания вашего кода какой-нибудь младший сотрудник сломает ту часть кода, которая выполняет «контроллер вызывает такой-то метод в определенном порядке»?

  2. Какова будет цена для вашей организации, если такое произойдет — сбой в работе производства, отладка/исправление/повторное тестирование/перевыпуск, юридический/финансовый риск, репутационный риск и т. д.?

Теперь перемножьте №1 и №2 и проверьте, стоит ли ваше нежелание достичь разумного объема тестового покрытия риска.

Иногда этого не будет (именно поэтому в тестировании есть понятие точки убывающей отдачи).

Например.Если вы поддерживаете веб-приложение, которое не является критически важным для производства, и у вас есть 100 пользователей, у которых есть обходной путь, если приложение сломалось (и/или вы можете выполнить простой и немедленный откат), то тратить 3 месяца на полное тестирование этого приложения, вероятно, не стоит. -чувственный.

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

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

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