Разработка через тестирование

редактировать
Разработка с использованием тестовых примеров

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

Американский инженер-программист Кент Бек, который приписывают эту программу или «переоткрытие» техники, заявлено в 2003 году, что TDD использует простые конструкции и вселяет уверенность.

Тестирование - управляемая разработка связана с концепцией программирования «сначала тестирование» экстремального программирования, начатой ​​в 1999 году, но в последнее время она сама по себе вызвала более общий интерес.

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

Содержание

  • 1 Цикл разработки на основе тестирования
  • 2 Стиль разработки
    • 2.1 Сохраняйте небольшой размер блока
  • 3 Лучшие практики
    • 3.1 Структура теста
    • 3.2 Отдельные лучшие практики
    • 3.3 Методы, которые исключены, или «анти-шаблоны»
  • 4 Преимущества
  • 5 Ограничения
  • 6 Тестирование работы
  • 7 TDD и ATDD
  • 8 TDD и BDD
  • 9 Видимость кода
  • 10 Программное обеспечение для TDD
    • 10.1 Фреймворки xUnit
    • 10.2 Результаты TAP
  • 11 Подделки, имитации и интеграционные тесты
  • 12 TDD для сложных систем
    • 12.1 Проектирование для обеспечения тестируемости
    • 12.2 Управление тестами для больших команд
  • 13 См. Также
  • 14 Ссылки
  • 15 Внешние ссылки

Цикл разработки, управляемое тестирование

Графическое представление Жизненный цикл разработки через тестирование

Следующая последовательность на книге «Разработка через тестирование на примере»:

1. Добавить тест
При разработке через тестирование каждая новая функция начинается с написания теста. Напишите тест который, укажите функцию или улучшения функции, который должен быть очень кратким. Чтобы написать тест, разработчик должен четко понимать спецификацию и требования функции. Разработчик может добиться этого с помощью вариантов использования и пользовательских историй, чтобы охватить требования и условия исключения, и может написать тест в любой среде тестирования, подходящей для программной среды. Это может быть модифицированная версия существующего теста. Это отличительная черта разработки через тестирование по сравнению с написанием модульных тестов после написания кода : это заставляет разработчика сосредоточиться на требованиях перед написанием кода - тонкое, но важное отличие.
2. Запустите все тесты и посмотрите, не прошел ли новый тест
Это подтверждает правильность работы тестовой оснастки, показывает, что новый тест не проходит, не требуется нового кода, требуемое поведение уже существует, и это исключает возможность того, что новый тест некорректен и всегда будет проходить успешно. Новый тест должен завершиться неудачно по ожидаемой причине. Этот шаг повышает уверенность в новом тесте.
3. Напишите код
Следующим шагом будет написание кода, который заставит тест пройти. Новый код, написанный на этом этапе, может, например, неэлегантно пройти проверку. Это приемлемо, потому что на шаге 5 он будет улучшен и отточен. На этом этапе единственная цель написанного кода - пройти тест. Программист не должен писать код, который выходит за рамки проверяемых тестом функций.
4. Выполнение тестов
Если все тестовые случаи теперь пройдены, программист может быть уверен, что новый код соответствует требованиям тестирования, а не нарушает и не выполняет какие-либо функции. Если они этого не сделают, новый код необходимо откорректировать, пока они не сделают этого.
5. Код рефакторинга
Растущая база кода должна регулярно очищаться во время разработки через тестирование. Новый код можно переместить с того места, где он был удобен для прохождения теста, туда, где он более логичен. Дублирование необходимо удалить. Имена объекта, класс, модуля, стандартные и методы должны четко отражать их текущее назначение и использование, так как добавлен дополнительный функционал. По мере добавления функций тела методов становиться длиннее, а другие объекты - больше. Они выигрывают от разделения и тщательного наименования их частей для улучшения удобочитаемости и ремонтопригодности, что будет приобретать все большую ценность в жизненном цикле программного обеспечения. Иерархии наследований можно перестроить, чтобы сделать их более логичными и полезными, возможно, извлечь выгоду из признанных шаблонов проектирования . Существуют авторитеты и общие рекомендации по рефакторингу и создание чистого кода. Постоянно повторяя тестовые примеры на каждом этапе рефакторинга, разработчик может быть уверен, что процесс не изменяет какие-либо функциональные возможности. Концепция устранения проблем важного аспектаом любой разработки программного обеспечения. В этом случае, однако, это также относится к удалению любого дублирования между тестовым кодом и производственным кодом - например, магические числа или строки, повторяющиеся в обоих, чтобы пройти тест на шаге 3.
Повторить
Начало с другого нового теста, цикл затем повторяется, чтобы продвинуть функциональность вперед. Размер шагов всегда должен быть небольшим, от 1 до 10 изменений между каждым запуском теста. Если новый код быстро не удовлетворяет требованиям нового теста или другие тесты неожиданно завершаются неудачно, программист должен отменить или вернуться к чрезмерной отладке. Непрерывная интеграция помогает, предоставляя обратимые контрольные точки. При использовании внешних библиотек важно не делать приращений, которые малы, чтобы эффективно тестировать саму библиотеку, за исключением случаев, когда есть какие-то основания полагать, что библиотека содержит ошибки или недостаточно полнофункциональна, чтобы удовлетворить все потребности программного обеспечения, находящееся в стадии разработки.

Стиль разработки

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

Для реализации некоторой продвинутой концепции, такой как шаблон проектирования, пишутся тесты, которые генерируют этот дизайн.

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

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

Сохраняйте единицу небольшого размера

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

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

Передовые методы разработки через испытания могут привести к . Разработка через приемочные испытания (ATDD) и Спецификации на примере, где проверяются алгоритмы работы приемочные испытания, которые затем управляют традиционным разработка на основе модульного тестирования (UTDD). Этот процесс гарантирует, что у заказчика есть автоматизированный механизм, позволяющий решить, соответствует ли программное обеспечение его требованиям. ATDD у команд разработчиков теперь есть конкретная цель, которую нужно выполнить - приемочные испытания, которые позволяют им постоянно концентрироваться на том, чего действительно хочет заказчик от пользовательской истории.

Лучшие практики

Структура теста

Эффективная структура тестового примера обеспечивает выполнение всех требуемых действий, улучшает читаемость тестового примера и сглаживает поток выполнения. Последовательная структура помогает в создании самодокументируемого тестового примера. Обычно применяется структура для тестовых случаев включает (1) настройку, (2) выполнение, (3) проверку и (4) очистку.

  • Настройка: перевод тестируемого устройства (UUT) или всей тестовой системы в состояние необходимого для запуска теста.
  • Выполнение: запуск / запуск UUT для выполнения целевого поведения и захвата всех выходных данных, таких как возвращаемые значения и выходные параметры. Этот шаг обычно очень простой.
  • Проверка убедитесь, что результаты теста верны. Эти результаты могут вызывать явные выходные данные, полученные во время выполнения, или изменения состояния проверяемого оборудования.
  • Очистка: восстановление проверяемого оборудования или всей тестовой системы до состояния перед тестированием. Это восстановление позволяет выполнить еще один тест сразу после этого.

Отдельные передовые практики

Некоторые передовые практики, которым может следовать отдельный человек, заключаются в разделении общей логики настройки и разрыва используются службы тестирования с помощью соответствующих тестовых примеров, чтобы каждый тестовый оракул Проверен только на результаты, необходимые для проверки его теста, работают, связанные со временем, системой, не работающей в режиме реального времени. Обычная практика допуска 5–10 процентной маржи для позднего выполнения снижает потенциальное количество ложноотриц результатов при выполнении теста. Также предлагается рассматривать тестовый код с тем же уважением, что и производственный код. Тестовый код должен работать правильно как для положительных, так и для отрицательных случаев, длиться долгое время, быть читаемым и поддерживаемым. Команды могут собираться вместе и анализировать тесты и методы тестирования, чтобы поделиться эффективными методами и выявить вредные привычки.

Методы, которые исключены, или «анти-шаблоны»

  • Наличие тестовых примеров зависит от ранее выполненных тестовых примеров (т. Е. Вы всегда должны запускать модульный тест из известных и известных случаев) созданного настроенного состояния).
  • Зависимости между тестовыми примерами. Набор тестов, в котором тестовые тесты зависят друг от друга, непостоянен и сложен. Не следует предполагать порядок исполнения. Базовый рефакторинг начальных тестовых примеров или структуры UUT спираль все более повсеместного воздействия на связанные тесты.
  • Взаимозависимые тесты. Взаимозависимые тесты могут вызывать каскадные ложноотрицательные результаты. Сбой в раннем тестовом примере нарушает последующий тестовый пример, даже если в проверяемом оборудовании не существует фактической ошибки, увеличивая усилия по анализу дефектов и отладке.
  • Проверка точного времени выполнения или производительности.
  • Строительство "всезнающие оракулы". Оракул, который проверяет больше, чем необходимо, со временем становится более дорогим и хрупким. Эта очень распространенная ошибка опасна, потому что она вызывает незначительный, но повсеместный расход времени в сложном проекте.
  • Детали реализации тестирования.
  • Медленное выполнение тестов.

Преимущества

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

Программисты, использующие чистый TDD в новых («greenfield »), сообщали, что они лишь изредка испытывали потребность в использовании отладчик . Используется вместе с системой управления версиями , когда тесты неожиданно завершаются неудачно, проходит код к последней версии, прошедшие все тесты, часто может быть более продуктивным, чем отладка.

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

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

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

TDD может привести к более модульному, гибкому и расширяемому коду. Проблема часто возникает из-за того, что методология требует, чтобы разработчики были протестированы независимо, а интегрированы вместе. Это приводит к меньшим, более сфокусированным классам, более слабой связи и более чистым интерфейсам. Использование шаблона проектирования фиктивного объекта обеспечивает общую модульность кода, поскольку этот шаблон требует, чтобы код был написан так, чтобы можно было легко переключать между фиктивными версиями для модульного тестирования и «настоящими» версиями. для развертывания.

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

Мадейски предоставил эмпирические доказательства (через серию лабораторных экспериментов с более чем 200 разработчиками) о превосходстве практики TDD над традиционным подходом Test-Last или подходом тестирования на правильность в отношении более низкой связи между объектами (CBO). Средняя величина эффекта представляет собой средний (но близкий к большому) эффект на основе метаанализа проведенных экспериментов, что является важным выводом. Он предлагает лучшую модульность (т.е. более модульную конструкцию), более легкое повторное использование и тестирование разработанных программных продуктов благодаря практике программирования TDD. Мадейски также измерил влияние практики TDD на модульные тесты, используя покрытие ветвей (BC) и индикатор оценки мутаций (MSI), которые являются индикаторами тщательности и эффективности обнаружения ошибок модульных тестов, соответственно. Влияние TDD на покрытие ветвей было средним по размеру и поэтому считается существенным.

Ограничения

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

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

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

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

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

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

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

Работа, управляемым тестированием

Разработка, управляемым тестированием, принята за пределами разработки программного обеспечения, как в группах продуктов, так и в сервисных группах, как работа, управляемым тестированием. Подобно TDD, команды, не связанные с программными элементами, перед началом работы выполняют проверку качества (QC) (обычно ручные, а не автоматические) для каждого аспекта работы. Эти проверки QC используются для информирования проекта и связанных результатов. Шесть шагов последовательность TDD применяются незначительными семантическими изменениями:

  1. «Добавить проверку» заменяет «Добавить тест»
  2. «Выполнить все проверки» заменяет «Выполнить все тесты»
  3. «Выполнить работу» заменяет «Напишите код»
  4. «Выполнить все проверки» заменяет «Выполнить тесты»
  5. «Выполнить работу» заменяет «Код рефакторинга»
  6. «Повторить»

TDD и ATDD

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

TDD и BDD

BDD (разработка, управляемое поведение ) сочетает в себе практики TDD и ATDD. Он включает в себя сначала практикует тесты, но фокусируется на тестах, которые описывают поведение, а не на тестах, которые проверяют единицу реализации. Такие инструменты, как Cucumber и Specflow, включают синтаксисы, которые позволяют владельцам продуктов, разработчикам и инженерам по тестированию определять поведение, которое может быть преобразовано в автоматизированные тесты.

Видимость кода

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

В объектно-ориентированном дизайне это все еще не обеспечивает доступа к частным данным и методам. Поэтому для модульных тестов может потребоваться дополнительная работа. В Java и других языках разработчик может использовать отражение для доступа к закрытым полям и методам. В качестве альтернативы можно использовать внутренний класс для хранения модульных тестов, чтобы они имели видимость и атрибутов включающего класса. В .NET Framework и некоторых других языках программирования частичные классы могут найти доступа к закрытым методам и данным для тестов.

Важно, чтобы такие тестовые хаки не остались в рабочем коде. В C и других языках директивы компилятора, такие как #if DEBUG... #endif, могут быть размещены вокруг таких дополнительных классов и всех других связанных с тестами код, чтобы предотвратить их компиляцию в выпущенный код. Это означает, что выпущенный код не совсем такой, как тот, который был протестирован модулем. Регулярное выполнение меньшего количества, но более полных, сквозных интеграционных тестов в окончательной сборке может (помимо прочего), что не существует производственного кода, который тонко полагается на аспекты тестовой оснастки.

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

Программное обеспечение для TDD

Существует множество структур и инструментов, тестирующих полезны в TDD.

Фреймворки xUnit

Разработчики используют компьютеризированные фреймворки тестирования, обычно под общим названием xUnit (которые являются производными от SUnit, созданного в 1998 году), чтобы создать и автоматически запускать тестовые наборы. Инфраструктуры xUnit предоставляет возможности проверки тестов в стиле утверждений и составления отчетов о результатах. Эти критически важные функции для автоматизации, поскольку они переносят бремя проверки выполнения с независимой операции постобработки операции, которая включается в выполнение теста. Среда выполнения, предоставляемая этими средами тестирования, позволяет автоматически выполнять все системные тестовые примеры или различные подмножества вместе с другими функциями.

Результаты TAP

Среды тестирования могут принимать выходные данные модульных тестов на языке -agnostic Test Anything Protocol, созданный в 1987 году.

Подделки, макеты и интеграционные тесты

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

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

  1. Если в окончательном проекте требуется внешний доступ, необходимо определить интерфейс, описывающий доступный доступ. См. принцип инверсии зависимостей для понимания преимуществ этого независимо от TDD.
  2. Интерфейс должен быть реализован двумя способами, один из которых действительно обращается к внешнему процессу, и другие из которых являются подделкой или имитацией. Поддельные объекты должны делать больше, чем сообщения, в журнал трассировки, по которому можно запустить тестовое утверждение для проверки правильного поведения. Мок-объекты отличаются тем, что сами содержат утверждения теста, которые могут быть к сбою теста, например, если имя человека и другие данные соответствуют ожидаемым.

Методы фальшивых и имитирующих объектов, которые возвращают данные, якобы из хранилища данных или пользователей, могут помочь процессу тестирования, всегда возвращаются одни и те же реалистичные данные, на которые могут полагаться тесты. Они также могут быть настроены на предопределенные режимы сбоев, чтобы можно было разработать и надежно протестировать процедуры обработки ошибок. В режиме сбоя метод может вызвать недопустимый, неполный или нулевой ответ либо вызвать исключение . Фальшивые сервисы, отличные от хранилища данных, также могут быть полезны в TDD: фальшивые сервисы шифрования фактически не могут шифровать передаваемые данные; Служба поддельных случайных чисел всегда может возвращать 1. Поддельные или имитирующие реализации используются примерами Испытуемый опыт.

Test Double - это специфическая для теста возможность, которая заменяет возможность системы, обычно класс или функцию, которую тестируемое устройство зависит от. Есть два момента, когда тестовые двойники могут быть введены в систему: ссылка и выполнение. Подстановка времени ссылки - это когда тестовый дубль компилируется в загрузочный модуль, который выполняется для проверки тестирования. Этот подход обычно используется при работе в среде, отличной от программы, которая требует дублирования аппаратного уровня для компиляции. Альтернативой замене компоновщика является замена во время выполнения, при которой реальная функциональность заменяется во время выполнения тестового примера. Эта замена обычно выполняется путем замены известных функций переназначения или объекта.

Тестовые двойники бывают разных типов и сложности:

  • Манекен - Манекен - это простейшая форма тестового двойника. Он упрощает замену времени компоновщика, предоставляя возвращаемое значение по умолчанию там, где это необходимо.
  • Заглушка - Заглушка упрощенную логику к файлу, фиктивные выходные данные.
  • Шпион - Шпион захватывает и делает доступным параметр и информация о состоянии, публикация аксессоров для тестового кода для частной информации, позволяющая более продвинутую проверку состояния.
  • Мок - Мок задает тестовым примером для поведения, специфического для теста.
  • Симулятор - Симулятор - это комплексный компонент, обеспечивающий более точную аппроксимацию функций (удваиваемой). Симулятор обычно требует значительных усилий по разработке.

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

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

  • Метод TearDown, который является неотъемлемой частью многих тестовых сред.
  • попробуй... поймай... наконецобработка исключений структур, если они доступны.
  • транзакции базы данных, где транзакция атомарно включает, возможно, запись, чтение и соответствующее удаление.
  • Принятие "снимок" базы данных перед запуском любых тестов и откат к снимку после каждого запуска теста. Это может быть автоматизировано с использованием инфраструктуры, такой как Ant или NAnt, или системы непрерывной интеграции, такой как CruiseControl.
  • Инициализация базы данных для чистого состояния перед испытаниями, а не уборка после них. Это может быть актуально, когда очистка может затруднить диагностику сбоев теста за счет

TDD для сложных систем

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

Проектирование с учетом тестируемости

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

  • High Cohesion гарантирует, что каждое устройство обеспечивает набор связанных возможностей и упрощает тестирование этих возможностей.
  • Low Coupling позволяет эффективно тестировать каждый блок изолированно.
  • Опубликованные интерфейсы ограничивают доступ к компонентам и служат точками контакта для тестов, облегчая создание тестов и обеспечивая высочайшее качество между тестовой и производственной конфигурацией единицы.

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

Управление тестами для больших команд

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

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

См. Также

Ссылки

Внешние ссылки

Последняя правка сделана 2021-06-10 02:34:34
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте