Что такое tdd в программировании
Перейти к содержимому

Что такое tdd в программировании

  • автор:

Обучение программированию через тестирование или TDD

Еще в XIX веке шотландский автор Самуэль Смайлс написал: «Мы учимся мудрости на ошибках гораздо быстрее, чем на успехах». Этому утверждению созвучны многие методологии разработки, где особое место уделяется тестированию, — например, DevOps и Agile. Лучшей считается та проверка, которая быстро находит ошибки. Если баги не обнаружены — цикл неудачный.

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

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

Это не означает, что обучение через одну лишь практику эффектно. Необходима правильная градация. Такая, где на первом месте — анализ возможных ошибок. Это Test-Driven Development (TDD), или разработка через тестирование — частное направление экстремального программирования. Суть этого принципа сводится к следующему:

  1. Составляется тест для небольшого отрывка кода, описывающего «базу».
  2. Создается код, прогоняется тест.
  3. По мере увеличения объема кода тест прогоняется повторно, каждый раз подтверждая правильность.

Отметим плюсы такого подхода:

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

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

Чтобы погрузиться в тему TDD, почитайте классные вводные статьи:

  1. Обзорный текст на Habr.
  2. Подробная статья на Technology Conversations.
  3. Наглядный туториал на Agile Data.
  4. Тест на вашу совместимость с TDD на Scott Logic.

И несколько книг:

  1. Экстремальное программирование: разработка через тестирование. Кент Бек.
  2. The Art of Unit Testing: With Examples in .NET. Roy Osherove.
  3. xUnit Test Patterns: Refactoring Test Code. Gerard Meszaros.
  4. Test-Driven Web Development with Python. Harry Percival.
  5. Growing Object-Oriented Software, Guided by Tests, Steve Freeman.

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

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

TDD, test-driven development или процесс разработки через тестирование — это методология разработки программного обеспечения, которая основывается на повторении коротких циклов разработки:

  1. Пишется тест, покрывающий желаемое изменение.
  2. Пишется программный код, который реализует желаемое поведение системы и позволяет пройти написанный тест.
  3. проводится рефакторинг написанного кода с постоянной проверкой прохождения всех тестов.

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

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

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

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

Цикл разработки по TDD

  • Добавить тест для новой (еще не реализованной) функциональности или для воспроизведения существующего бага
  • Запустить все тесты и убедиться, что новый тест не проходит
  • Написать код, который обеспечит прохождение теста:
  • Запустить тесты и убедиться, что они все прошли успешно: прохождение нового теста подтверждает реализацию нового функционала или исправление существующей ошибки, а прохождение остальных позволяет удостовериться, что ранее реализованный функционал работает по‑прежнему корректно.
  • Заняться рефакторингом и оптимизацией — улучшение сопровождаемости и быстродействия целесообразно осуществлять уже после того, как получилось добиться проверяемой работоспособности
  • Перезапустить тесты и убедиться, что они все ещё проходят успешно
  • Повторить цикл

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

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

Статья опубликована в 2014 и была обновлена в 2023 году

Тематические статьи

Стандарты кодирования — залог хорошей сопровождаемости проекта

Любая командная разработка может быть эффективной только в том случае, если участники команды имеют общее видение.

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

методологии разработки
веб-разработка
Статья опубликована в 2014 и обновлена в 2023 году

SOLID — принципы объектно‑ориентированного программирования

SOLID это аббревиатура пяти основных принципов проектирования в объектно‑ориентированном программировании, предложенных Робертом Мартином:

  • Single responsibility — принцип единственной ответственности
  • Open-closed — принцип открытости / закрытости
  • Liskov substitution — принцип подстановки Барбары Лисков
  • Interface segregation — принцип разделения интерфейса
  • Dependency inversion — принцип инверсии зависимостей

веб-разработка
методологии разработки
Статья опубликована в 2019 и обновлена в 2023 году

Принцип программирования YAGNI — «Вам это не понадобится»

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

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

методологии разработки
веб-разработка
Статья опубликована в 2019 и обновлена в 2023 году

Принцип программирования KISS — делайте вещи проще

KISS — это принцип проектирования и программирования, при котором простота системы декларируется в качестве основной цели или ценности.

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

методологии разработки
веб-разработка
Статья опубликована в 2019 и обновлена в 2023 году

Принцип программирования DRY — don’t repeat yourself / не повторяйте себя

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

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

веб-разработка
методологии разработки
Статья опубликована в 2018 и обновлена в 2023 году

Флаги функций (Feature Flags)

Флаги функций позволяют отделить развертывание функций от развертывания кода, обеспечивают возможности для A/B-тестирования и предоставляют механизм быстрого отключения проблемных функций

методологии разработки
Статья опубликована в 2023 году

Модель ветвления Trunk Based Development (TBD)

Trunk Based Development (TBD) или транковая разработка — модель ветвления системы управления версиями, при которой все разработчики работают в одной ветке. Эта модель имеет значительные преимущества с точки зрения совместной работы, качества кода и скорости доставки изменений.

методологии разработки
Статья опубликована в 2023 году

Процессы, необходимые для информационной безопасности

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

Взломы, утечки данных и неработоспособность ключевых систем приводит как к финансовых потерям, так и к репутационным издержкам. Чтобы снизить риски в сфере ИБ стоит внедрять базовые процессы ИБ в разработку, тестирование и системное администрирование.

информационная безопасность
веб-разработка
тестирование
системное администрирование
Статья опубликована в 2020 и обновлена в 2023 году

MVC — модель‑представление-контроллер

MVC — это паттерн проектирования приложений, который разделяет на три отдельных компонента модель данных приложения, пользовательский интерфейс и слой взаимодействия с пользователем.

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

Что такое TDD

TDD — это аббревиатура от test-driven development (разработка через тестирование). Она широко известна в IT-индустрии благодаря книге Кента Бека по программной инженерии “Экстремальное программирование”. В этом бестселлере представлен новый метод разработки программного обеспечения — экстремальное программирование.

Смысл названия “экстремальное программирование” кроется в главной идее этого метода — доведении обычной практики программирования до предела совершенства. Поэтому TDD — один из наиболее часто рекомендуемых методов.

На приведенном ниже изображении представлена классическая модель TDD:

Модель TDD отражает три этапа этого метода.

  1. Написание контрольного примера непрохождения теста для функции.
  2. Создание правильного кода для функции, чтобы тест был пройден.
  3. Рефакторинг кода.

Считается, что разработка через тестирование заключается в том, чтобы начать с создания тестов, а лишь затем переходить к написанию кода. Это неправильное понимание. Сперва тест, потом код — это скорее Test-First Development (предварительная разработка тестов), а не Test-Driven Development (разработка через тестирование).

Отличие второго понятия от первого заключается в “драйвере” или, говоря более конкретно, в одном шаге — рефакторинге!

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

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

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

Как эффективно выполнять TDD

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

Поскольку TDD приобрел большую популярность, Кент Бек посвятил этому методу отдельную книгу под названием “Разработка через тестирование”. Основную ее идею можно выразить так — декомпозиция по заданиям.

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

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

Кажется, что все просто, однако большинство разработчиков так не поступают. Почему?

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

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

Так в чем же польза?

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

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

TDD — инструмент профессионалов

Итак, метод TDD внес новые идеи в разработку программного обеспечения.

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

Такая практика не только позволит улучшить качество кода, но и повысит производительность.

  • TDD и обработка исключений в ASP.NET Core с помощью xUnit
  • Визуализация стратегии автоматизированного тестирования
  • Мутационное тестирование: создай мутанта и прокачай тест

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

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

Обычная разработка выглядит так: пишем код → тестируем → смотрим, что не прошло, и исправляем код. И так повторяем до тех пор, пока все тесты не сработают. Разработка через тестирование — это обратный подход.

Коротко суть TDD (test-driven development)

Разработка через тестирование — это подход, при котором тесты создаются раньше кода. Вот так:

  1. Перед тем как писать код, программисты задают для себя критерии рабочего кода. Например, какой-то модуль программы при запросе «Прачечная» должен гарантированно отвечать «Министерство культуры».
  2. Программист сразу пишет тест «Запрос такой-то — ожидать ответ такой-то».
  3. Так как требований и кейсов к модулю может быть много, тестов тоже получается целая батарея.
  4. Дальше пишется код этого модуля.
  5. Как только код готов, включают батарею тестов и смотрят, чтобы они прошли корректно.
  6. Так повторяется для каждого модуля, каждого маленького закутка, и при каждом обновлении программы прогоняются все тесты.

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

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

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

Коротко суть TDD (test-driven development)

Плюсы и минусы TDD (Test-driven development)

Плюсы разработки через тестирование:

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

Минусы такого подхода:

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

Разработка через поведение (BDD)

Кроме разработки через тестирование, есть разработка через поведение, или BDD (Behavior-driven development). Здесь мы смотрим не на ввод-вывод данных, а на поведение программы: как с ней взаимодействует пользователь и что она ему выдаёт.

В поведенческом подходе тесты пишут в формате Given-When-Then (Дано — Когда — Тогда), чтобы сразу привязать код к логике работы проекта. Пример теста BDD:

Scenario: Клиент должен быть авторизован, чтобы иметь доступ к личному кабинету

Given пользователь открывает личный кабинет

When пользователь не авторизован

Then отображаем отказ

Что дальше

В следующий раз мы познакомимся с BDD-сценариями поближе: посмотрим на инструменты и попробуем написать сценарий к какому-нибудь нашему проекту.

Тестирование — это билет в ИТ

Простой вход в мир ИТ, ваша первая работа и быстрый старт в профессии. Изучите основы — и за дело. Мы поможем с обучением и трудоустройством. Старт бесплатно.

Тестирование — это билет в ИТ Тестирование — это билет в ИТ Тестирование — это билет в ИТ Тестирование — это билет в ИТ

Получите ИТ-профессию

В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *