Что такое tdd bdd ddt kdt

TDDx2, BDD, DDD, FDD, MDD и PDD, или все, что вы хотите узнать о Driven Development

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

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

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

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

TDD — Test Driven Development

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

Звучит просто и понятно. Многим знаком такой подход к разработке и даже сам “Uncle Bob” активно его пропагандирует.

TDD считается одной из форм правильного метода построения приложения. Философия разработки на основе тестов заключается в том, что ваши тесты являются спецификацией того, как ваша программа должна вести себя. Если вы рассматриваете свой набор тестов как обязательную часть процесса сборки, если ваши тесты не проходят, программа не собирается, потому что она неверна. Конечно, ограничение заключается в том, что правильность вашей программы определена только как полнота ваших тестов. Тем не менее, исследования показали, что разработка, основанная на тестировании, может привести к снижению ошибок на 40–80% в производстве.

Начав использовать TDD, вы можете почувствовать, что работаете медленнее, чем обычно. Так происходит потому что вы будете работать вне «зоны комфорта», и это вполне нормально.

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

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

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

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

TDD — Type Driven Development

Type Driven Development сокращенно пишется также, как и разработка через тестирование, поэтому обычно пишут полное название.

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

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

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

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

BDD — Behaviour Driven Development

Из-за некоторого методологического сходства TDD (Test Driven Development) и BDD (Behaviour Driven Development) часто путают даже профессионалы. В чем же отличие? Концепции обоих подходов похожи, сначала идут тесты и только потом начинается разработка, но предназначение у них совершенно разное. TDD — это больше о программировании и тестировании на уровне технической реализации продукта, когда тесты создают сами разработчики. BDD предполагает описание тестировщиком или аналитиком пользовательских сценариев на естественном языке — если можно так выразиться, на языке бизнеса.

BDD — behaviour-driven development — это разработка, основанная на описании поведения. Определенный человек(или люди) пишет описания вида “я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке” (там есть специально выделенные ключевые слова). Программисты давно написали специальные тулы, которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.

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

Тексты сценариев записываются в определенной форме.

Имея (прим. given — данное) какой-то контекст,

Когда (прим. when) происходит событие,

Тогда (прим. then) проверить результат.

Источник

Блог компании

DDD, BDD, TDD и другие «DD»

Попробуем немного разобраться.

Откуда взялось так много парадигм?

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

Все зависит от того, что требуется сделать. Стоит отметить, что все средства разработки отличаются, одни поддерживают одно, другие — другое. К примеру, PHP со «стандартным» набором модулей не поддерживает аспектно-ориентированное программирование. Поэтому выбор методологии довольно тесно связан с платформой разработки. Ну, и не стоит забывать, что можно комбинировать разные подходы, что приводит нас к выбору стека парадигм.

Для категоризации парадигм я использую 4 измерения, которые присущи практически любой задаче:

1. Данные.
Любая программа, так или иначе, работает с данными: хранит их, обрабатывает, анализирует, передает.

2. Действия.
Любая программа должна что-то делать, обычно действия связанны с данными.

3. Логика.
Логика или бизнес-логика определяет правила, которым подчиняются данные и действия. Без логики программа лишена смысла.

4. Интерфейс.
То, как программа взаимодействует с внешним миром.

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

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

1. Ориентация на данные (Data Driven Design).Нам важны в первую очередь данные, а не то, как они между собой связанны.
Типы подходящих приложений:
— СУБД
— грабберы (собираем данные из разных источников, сохраняем куда-нибудь)
— различные админки, интерфейсы к базам данным
— случаи, когда работа с данными уже определена, например, требуется разработать программу, а база данных уже существует и схему данных не изменить. В таком случае возможно проще ориентироваться на то, что уже есть, чем создавать дополнительные обертки над данными и уровнями доступа к данным.
— часто ориентация на данные появляется при использовании ORM, но нельзя заранее сказать хорошо это, или плохо (об этом ниже)

2. Ориентация на действия — императивные подходы к разработке. Думаю, что сюда можно отнести такие парадигмы как Event Driven Programming, Aspect Oriented Programming.

3. Ориентация на логику — Domain Driven Design (DDD) и все, что с этим связанно. Здесь нам важна предметная область задачи, мы уделяем внимание моделированию объектов, анализу связей и зависимостей. Применяется преимущественно в бизнес приложениях.
Так же, сюда относится декларативный подход и отчасти функциональное программирование (решение задач, которые хорошо описываются математическими формулами)

4. Ориентация на интерфейс. Используется, когда в первую очередь важно как программа взаимодействует с внешним миром.
Разработка приложения с ориентацией только на интерфейс — ситуация довольно редкая. Хотя в некоторых книгах я встречал упоминание о том, что такой подход рассматривался в серьез, причем базируясь на пользовательском интерфейсе — брали, что непосредственно видит пользователь и, исходя из этого, проектировали структуры данных и все остальное.
Ориентация на пользовательский интерфейс в бизнес приложениях часто проявляется косвенно: к примеру, пользователю требуется видеть определенные данные, которые получить сложно, за счет чего архитектура обрастает дополнительными конструкциями (например, вынужденной избыточностью данных).
Формально сюда можно отнести Event Driven Programming.

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

На основе моего опыта могу сказать, что в данной сфере превалируют два подхода: ориентация на данные (Data Driven) и ориентация на логику (Domain Driven). По сути, они являются конкурирующими методологиями, но на практике могут объединяться в симбиозы, которые часто являются известными анти-паттернами.

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

В свою очередь Domain Driven выигрышен на крупных проектах, а на небольших — приводит к усложнению решения и требует больше ресурсов для разработки, что часто бывает критичным с точки зрения бизнес требований (вывести проект на рынок «asap», за небольшой бюджет).

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

· Квота (отправляется клиенту как предложение)

· Билл (по сути, платежка от поставщика)

Решив, что контекстная область у нас как на ладони, мы начинаем проектировать базу данных. Создаем соответствующие таблицы, запускаем ORM-ку, генерируем сущностные классы (ну, или в случае «умной» orm-ки прописываем схему где-то отдельно, например, в хml, и уже по ней генерируем и базу и сущностные классы). В итоге получаем на каждую сущность отдельный, независимый класс. Радуемся жизни, работать с объектами легко и просто.

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

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

Проходит время, и появляется логика, которую не описать внешними связами в бд, и поэтому разместить ее в сущностных классах нет возможности. Мы начинаем создавать сервисы, которые выполняют эти функции. В итоге получаем, что бизнес логика разбросана по сущностным классам и сервисам, понять, где искать нужный метод становится все сложнее. Решаем провести рефакторинг и вынести, к примеру, повторяющейся код в сервисы — выделяем общий функционал в интерфейс (например, делаем интерфейс — IProductable, т.е. нечто, что содержит продукты), сервисы могут работать с этими интерфейсами, за счет чего немного выигрываем в абстракции. Но кардинально это не решает проблему, получаем больше методов в сервисах и решаем для единства картины перенести все методы из сущностных классов в сервисы. Теперь мы знаем, где искать методы, но наши сущностные классы лишись всякой логики, и мы получили так называемую «Анемичную модель» (Anemic Model).

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

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

Как вы наверно догадались, этот сценарий описывает использование Data Driven подхода и его проблемы.

В случае с Domain Driven мы бы поступили следующим образом. Во-первых, ни о каком проектировании бд на первом этапе речи бы не шло. Нам потребовалось бы тщательно проанализировали контекстную область задачи, смоделировать ее и перенести на язык ООП.

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

В итоге, контекстная область задачи будет описана используя ООП на полную катушку.

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

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

Итак, подведем итог Data Driven vs Domain Driven:

o Позволяет быстро разработать приложение или прототип

o Удобно проектировать (кодогенерация по схеме и тп)

o На небольших или средних по размеру проектах может быть вполне себе решением

o Может приводить к анти-паттернам и уходу от ООП

o На больших проектах приводит к хаосу, сложной поддержке и т.п.

o Использует всю мощь ООП

o Позволяет контролировать сложность контекстной области (домена)

o Есть еще ряд преимуществ, не описанных в статье, например, создание доменного языка и внедрение BDD.

o Дает мощный инструмент для разработки сложных и больших решений

o Требует значительно больше ресурсов при разработке, что приводит к удорожанию решения

o Определенные части становятся сложнее в поддержке (мепперы данных и т.п.)

Так, что же, черт возьми, мне выбрать?

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

Источник

Что надо знать о TDD и BDD: как тесты помогают разработчикам работать в команде и понять заказчика

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

Java Developer в NIX

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

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

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

Чтобы в своей профессии вы не повторяли судьбу героев басни, были созданы методологии тестирования Test Driven Development (TDD) и Behavior Driven Development (BDD). Давайте разберемся, как они работают.

TDD и BDD: основные отличия модульного и интеграционного тестирования

Test Driven Development (TDD) — это разработка, основанная на тестировании. Предположим, вы получаете от заказчика запрос на добавление в разрабатываемый продукт нового функционала. Под этот запрос составляется техническая документация в виде тестов: в них согласованы и записаны новые требования, которые заказчик предъявляет к продукту.

Тестирование в TDD происходит через итерации (циклы) и соответствует такому порядку:

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

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

Методология TDD относится к юнит-тестированию (модульному тестированию) и позволяет проверять отдельно взятые части продукта. Чаще всего TDD пишут сами разработчики, тесты реализуются в виде программного кода.

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

В этом случае прибегают к использованию методологии Behavior Driven Development — разработке на основе поведения. В отличие от TDD, этот подход строится на написании нескольких пользовательских сценариев, под которые составляются тесты. BDD позволяет «‎предугадать», как поведет себя пользователь, используя продукт в соответствии с требованиями, которые записаны в технической документации. Порядок прохождения тестов схож с TDD. Единственное отличие — перед прохождением отдельных тестов формулируется ряд предварительных условий (сценариев), при которых они должны быть пройдены.

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

Сравненение BDD и TDD / TestLodge

Требования для BDD обычно составляет группа экспертов и не в виде программного кода, а словесно — на языке, понятном всем участникам проекта.

Behavior Driven Development относится к методам интеграционного тестирования. Оно позволяет понять, правильно ли взаимодействуют друг с другом отдельно взятые части программы.

Подход также эффективен в end-to-end-тестировании (Е2Е) и дает программистам представление о том, как функционирует вся разрабатываемая ими система. Получается, несмотря на то, что BDD и является расширением TDD-методологии, они имеют разное предназначение и реализуются разным набором инструментов.

В общем, мы друг друга поняли

Методологии BDD- и TDD- тестирования помогают достичь взаимопонимания между заказчиком продукта и всеми участниками, задействованными в его реализации.

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

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

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

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

Как составлять тесты?

Давайте подытожим кратким списком рекомендаций по составлению тестов:

Инструменты для реализации юнит-тестирования

Юнит-тестирование на Java осуществляется при помощи фреймворка JUnit. Он относится к семейству фреймворков xUnit и используется преимущественно для Test-Driven- и Behavior-Driven-разработки. На сегодня JUnit 5 — самая свежая версия фреймворка, которая совместима с версиями Java 8 и выше.

Это значит, что фреймворк поддерживает Stream API, лямбды, функциональные интерфейсы и массу других «плюшек», которые таит в себе Java 8+.

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

Что такое tdd bdd ddt kdt. Смотреть фото Что такое tdd bdd ddt kdt. Смотреть картинку Что такое tdd bdd ddt kdt. Картинка про Что такое tdd bdd ddt kdt. Фото Что такое tdd bdd ddt kdt

JUnit 5 состоит из трех отдельных пакетов, которые можно подключать независимо друг от друга

Экстеншн-модели и аннотации в JUnit 5

Экстеншн-модель в JUnit Jupiter — это разновидность совершенно нового API, позволяющая расширять функционал отдельного теста и добавлять новые условия для работы с ним. Для работы с экстеншн-моделью существуют экстеншн-поинты.

Существует пять основных видов экстеншн-поинтов:

В JUnit пятой версии также расширен функционал Assertions API. Например, теперь вы сможете работать с методом assertAll, который построен на использовании лямбд. Он позволяет производить групповые проверки: каждая следующая проверка выполняется только в том случае, если предыдущая верна:

JUnit 5 также позволяет контролировать выполнение теста в зависимости от внешних условий. Вы можете выбирать ОС, на которой будете проводить тестирование, а также версию Java, на которой будет работать тест. Контролировать можно и то, при каких системных настройках будет запущен тест.

Также JUnit 5 помогает создавать свои собственные аннотации. Для этого необходимо указать @Target (ElementType.METHOD) для нового интерфейса и затем перечислить все аннотации, которые должны сработать при подключении вашей аннотации. Вот несколько примеров таких аннотаций:

Тестируй себя сам

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

Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.

Источник

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

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