1 added
1 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>BDD - разработка через поведение. BDD для микросервисов - это сотрудничество клиента, разработчиков и тестировщиков. BDD - это разработка, которая учитывает и технические интересы и бизнес-требования. Этот подход обычно применяется для описания интерфейсов приложений, а так как микросервисы - детали реализации системы, то BDD прекрасно походит и для разработки микросервисов. Как это сделать - в переводе материала от<a>Ken Pugh</a>.</p>
1
<p>BDD - разработка через поведение. BDD для микросервисов - это сотрудничество клиента, разработчиков и тестировщиков. BDD - это разработка, которая учитывает и технические интересы и бизнес-требования. Этот подход обычно применяется для описания интерфейсов приложений, а так как микросервисы - детали реализации системы, то BDD прекрасно походит и для разработки микросервисов. Как это сделать - в переводе материала от<a>Ken Pugh</a>.</p>
2
<p>Поведение в BDD часто выражается конструкцией Given/When/Then. Нам дано определенное состояние, когда происходит действие или событие, тогда состояние изменяется и/или возвращается информация.</p>
2
<p>Поведение в BDD часто выражается конструкцией Given/When/Then. Нам дано определенное состояние, когда происходит действие или событие, тогда состояние изменяется и/или возвращается информация.</p>
3
<p>К примеру, stateless логика, такая как бизнес-правила и вычисления, просто описывает преобразование входных данных к выходным.</p>
3
<p>К примеру, stateless логика, такая как бизнес-правила и вычисления, просто описывает преобразование входных данных к выходным.</p>
4
<p>Интерфейсно-ориентированный дизайн - Interface Oriented Design, использует принцип "<strong>проектирования относительно интерфейсов, а не реализаций</strong>". Потребители сервиса используют интерфейс, который он предоставляет, а не внутренности. Это значит, что такой интерфейс должен быть четко продуман, включая поведение при ошибках. Для определения терминов в описании интерфейса или его поведения можно использовать DDD - Domain Driven Design.</p>
4
<p>Интерфейсно-ориентированный дизайн - Interface Oriented Design, использует принцип "<strong>проектирования относительно интерфейсов, а не реализаций</strong>". Потребители сервиса используют интерфейс, который он предоставляет, а не внутренности. Это значит, что такой интерфейс должен быть четко продуман, включая поведение при ошибках. Для определения терминов в описании интерфейса или его поведения можно использовать DDD - Domain Driven Design.</p>
5
<p>Микросервисы могут быть синхронными, когда потребитель<strong>напрямую вызывает другой сервис</strong>и ожидает результата, либо асинхронными, когда<strong>сервис отвечает на сообщение, которое клиент поместил в очередь.</strong></p>
5
<p>Микросервисы могут быть синхронными, когда потребитель<strong>напрямую вызывает другой сервис</strong>и ожидает результата, либо асинхронными, когда<strong>сервис отвечает на сообщение, которое клиент поместил в очередь.</strong></p>
6
<p>Рассмотрим пример синхронного сервиса.</p>
6
<p>Рассмотрим пример синхронного сервиса.</p>
7
<h2>Синхронный сервис</h2>
7
<h2>Синхронный сервис</h2>
8
<p>Представим сервис, который вычисляет скидку на заказ клиента.Весь процесс - набор связанных операций.</p>
8
<p>Представим сервис, который вычисляет скидку на заказ клиента.Весь процесс - набор связанных операций.</p>
9
<p>Поведение этого сервиса можно описать так:</p>
9
<p>Поведение этого сервиса можно описать так:</p>
10
Get discount for a customer Given these inputs Customer category Order Amount Then service outputs Discount Amount<p>Сервис может вычислить скидку используя алгоритмы в коде, на основании локальной базы данных данных или связавшись с другими сервисами.</p>
10
Get discount for a customer Given these inputs Customer category Order Amount Then service outputs Discount Amount<p>Сервис может вычислить скидку используя алгоритмы в коде, на основании локальной базы данных данных или связавшись с другими сервисами.</p>
11
<p>Он может использовать JSON или XML в качестве формата сообщений. Однако, описание сервиса без указания деталей реализации помогает отделить семантику операций от синтаксиса.</p>
11
<p>Он может использовать JSON или XML в качестве формата сообщений. Однако, описание сервиса без указания деталей реализации помогает отделить семантику операций от синтаксиса.</p>
12
<h2>Что такое поведение?</h2>
12
<h2>Что такое поведение?</h2>
13
<p>Используя BDD, можно начать проектирование с примера данных, чтобы получить представление о требуемом поведении. Разработчики сервиса, клиента и тестировщик могут прийти к такому примеру. Первые два столбца - входные данные для сервиса, а столбец справа - выходные.</p>
13
<p>Используя BDD, можно начать проектирование с примера данных, чтобы получить представление о требуемом поведении. Разработчики сервиса, клиента и тестировщик могут прийти к такому примеру. Первые два столбца - входные данные для сервиса, а столбец справа - выходные.</p>
14
<p>Пример показывает доменные термины, которым может потребоваться дальнейшее уточнение - например, описать допустимые значения.</p>
14
<p>Пример показывает доменные термины, которым может потребоваться дальнейшее уточнение - например, описать допустимые значения.</p>
15
<p>Подразумевается, что сервис возвращает правильный результат, если входные данные попадают в диапазон допустимых значений.</p>
15
<p>Подразумевается, что сервис возвращает правильный результат, если входные данные попадают в диапазон допустимых значений.</p>
16
<p>Описание поведения, особенно для микросервисов, часто включает ответы в случае сбоев и ошибок. Описание потенциальных сбоев помогает потребителю понять, что ему делать в таких случаях. Клиенты сервиса могут использовать специальные библиотеки, например, Hystrix от Netflix, для устранения некоторых из этих сбоев.</p>
16
<p>Описание поведения, особенно для микросервисов, часто включает ответы в случае сбоев и ошибок. Описание потенциальных сбоев помогает потребителю понять, что ему делать в таких случаях. Клиенты сервиса могут использовать специальные библиотеки, например, Hystrix от Netflix, для устранения некоторых из этих сбоев.</p>
17
<p>Некоторые потенциальные ошибки нашего сервиса:</p>
17
<p>Некоторые потенциальные ошибки нашего сервиса:</p>
18
<p>Сбои могут быть выражены в виде числовых или символьных констант в протоколе связи.</p>
18
<p>Сбои могут быть выражены в виде числовых или символьных констант в протоколе связи.</p>
19
<p>Использование значимых имен в BDD помогает подчеркнуть семантику сбоя, а не его синтаксис.</p>
19
<p>Использование значимых имен в BDD помогает подчеркнуть семантику сбоя, а не его синтаксис.</p>
20
<p>Если значения, которое передали в качестве категории, нет в списке допустимых значений, то сервис вернет индикатор сбоя: "Неверное значение параметров запроса". Это может быть представлено, например, возвратом HTTP c кодом 400 и соответствующим текстовым описанием.</p>
20
<p>Если значения, которое передали в качестве категории, нет в списке допустимых значений, то сервис вернет индикатор сбоя: "Неверное значение параметров запроса". Это может быть представлено, например, возвратом HTTP c кодом 400 и соответствующим текстовым описанием.</p>
21
<p>Альтернативно, можно определить значение скидки, которое будет возвращаться, например, 0, если какой-либо из параметров неверен. Сервис в таком случае должен нести ответственность за регистрацию этой проблемы, чтобы можно было проанализировать ее последствия.</p>
21
<p>Альтернативно, можно определить значение скидки, которое будет возвращаться, например, 0, если какой-либо из параметров неверен. Сервис в таком случае должен нести ответственность за регистрацию этой проблемы, чтобы можно было проанализировать ее последствия.</p>
22
<p>BDD-тесты сервиса могут формировать контекст для его модульных тестов. В процессе проектирования<strong>ответственность за прохождение тестов BDD возлагается на классы и методы</strong>. Модульные тесты определяют эти обязанности.</p>
22
<p>BDD-тесты сервиса могут формировать контекст для его модульных тестов. В процессе проектирования<strong>ответственность за прохождение тестов BDD возлагается на классы и методы</strong>. Модульные тесты определяют эти обязанности.</p>
23
<h2>Заглушки</h2>
23
<h2>Заглушки</h2>
24
<p>При тестировании сервиса часто требуются заглушки зависимых сервисов, которые он вызывает. Они особенно нужны для медленных, дорогих или случайных сервисов. Если поведение сервиса скидок никогда не менялось, то при тестировании клиента можно использовать боевой инстанс.</p>
24
<p>При тестировании сервиса часто требуются заглушки зависимых сервисов, которые он вызывает. Они особенно нужны для медленных, дорогих или случайных сервисов. Если поведение сервиса скидок никогда не менялось, то при тестировании клиента можно использовать боевой инстанс.</p>
25
<p>Изменения часто неизбежны, поэтому обычно заглушки нужны.</p>
25
<p>Изменения часто неизбежны, поэтому обычно заглушки нужны.</p>
26
<p>Заглушка может всегда отдавать одни и те же значения, например:</p>
26
<p>Заглушка может всегда отдавать одни и те же значения, например:</p>
27
<p>Тесты клиента могут опираться на эти значения. В этом примере постоянного поведения может быть достаточно. Для других тестов предпочтительнее настраиваемый ответ заглушки.</p>
27
<p>Тесты клиента могут опираться на эти значения. В этом примере постоянного поведения может быть достаточно. Для других тестов предпочтительнее настраиваемый ответ заглушки.</p>
28
<p>В качестве альтернативы, заглушка сервиса скидок может просто возвращать одну и ту же сумму, независимо от входных данных.</p>
28
<p>В качестве альтернативы, заглушка сервиса скидок может просто возвращать одну и ту же сумму, независимо от входных данных.</p>
29
<p>Как эта заглушка может вписаться в более широкий сценарий? Рассмотрим поведение системы для заказа, который включает в себя как скидку, так и налог. Налог рассчитывается микросервисом, аналогичным скидке.</p>
29
<p>Как эта заглушка может вписаться в более широкий сценарий? Рассмотрим поведение системы для заказа, который включает в себя как скидку, так и налог. Налог рассчитывается микросервисом, аналогичным скидке.</p>
30
<h2>Сервисы с состоянием</h2>
30
<h2>Сервисы с состоянием</h2>
31
<p>Если сервис скидок использует БД, чтобы получить информацию для расчета скидки, то ее содержимое - это состояние сервиса. Изменения состояния в ответ на обновления данных, должно быть задокументировано. Предположим, что сервис имел такое состояние.</p>
31
<p>Если сервис скидок использует БД, чтобы получить информацию для расчета скидки, то ее содержимое - это состояние сервиса. Изменения состояния в ответ на обновления данных, должно быть задокументировано. Предположим, что сервис имел такое состояние.</p>
32
<p>В таком случае, сервис должен позволять менять эти данные. Обновление может быть организовано так, чтобы обновляемыми были отдельные элементы или чтобы обновлялась вся таблица сразу. Вот пример поведенческого теста для индивидуального обновления.</p>
32
<p>В таком случае, сервис должен позволять менять эти данные. Обновление может быть организовано так, чтобы обновляемыми были отдельные элементы или чтобы обновлялась вся таблица сразу. Вот пример поведенческого теста для индивидуального обновления.</p>
33
-
<p>У сервиса скидок может быть локальное хранилище для сохранения данных в этом примере, но он может зависеть и от отдельного сервиса хранения этих данных. Если так, то тесты из предыдущего раздела применяются и к отдельному сервису. Но каждая зависимость добавляет проблемы. Каким должно быть поведение службы, если ее зависимости недоступны? Для сервиса скидок это должно указывать на сбой или он должен просто возвращать значение по-умолчанию, тот же 0? Иногда можно использовать глобальные политики обработки ошибок, но<strong>часто решение зависит от контекста сервиса</strong>.</p>
33
+
<p>У сервиса скидок может быть локальное хранилище для сохранения данных в этом примере, но он может зависеть и от отдельного сервиса хранения этих данных. Если так, то тесты из предыдущего раздела применяются и к отдельному сервису. Но каждая зависимость добавляет проблемы. Каким должно быть поведение службы, если ее зависимости недоступны? Для сервиса скидок это должно указывать на сбой или он должен просто возвращать значение по-умолчанию, тот же 0? Иногда можно использовать глобальные политики обработки ошибок, но<strong>часто решение зависит от ко��текста сервиса</strong>.</p>
34
<h2>Формулирование тестов и автоматизация</h2>
34
<h2>Формулирование тестов и автоматизация</h2>
35
<p>После того, как поведение микросервиса согласовано, его можно сформулировать в виде автоматизированных тестов. Существует несколько систем тестирования микросервисов, таких как PACT или Karate. Кроме того, вы можете использовать BDD-фреймворки, такие как Cucumber или FIT.</p>
35
<p>После того, как поведение микросервиса согласовано, его можно сформулировать в виде автоматизированных тестов. Существует несколько систем тестирования микросервисов, таких как PACT или Karate. Кроме того, вы можете использовать BDD-фреймворки, такие как Cucumber или FIT.</p>
36
<p>Например Cucumber, использует библиотеки для запросов к сервисам. Тогда дополнительная информация об окружении может быть представлена как часть сценария.</p>
36
<p>Например Cucumber, использует библиотеки для запросов к сервисам. Тогда дополнительная информация об окружении может быть представлена как часть сценария.</p>
37
<p>Например, файл объектов Cucumber может включать.</p>
37
<p>Например, файл объектов Cucumber может включать.</p>
38
<p>Варианты шагов зависят от ваших соглашений тестирования.</p>
38
<p>Варианты шагов зависят от ваших соглашений тестирования.</p>
39
<p>Значения в первых двух столбцах могут быть перенесены в любое соглашение о вызовах, например, в параметры запроса. Результат в body должен соответствовать третьему столбцу. Если имена и значения запроса - это имена и значения столбцов, это уменьшает различия между тестом и реализацией.</p>
39
<p>Значения в первых двух столбцах могут быть перенесены в любое соглашение о вызовах, например, в параметры запроса. Результат в body должен соответствовать третьему столбцу. Если имена и значения запроса - это имена и значения столбцов, это уменьшает различия между тестом и реализацией.</p>
40
<p>Для повторного использования шаги могут быть написаны для произвольного сервиса, который делает вычисления или определяет результат выполнения бизнес-правила. В приведенном выше примере использование символа "?", как в "Discount Amount" выше, помогает анализатору различать входные и выходные данные.</p>
40
<p>Для повторного использования шаги могут быть написаны для произвольного сервиса, который делает вычисления или определяет результат выполнения бизнес-правила. В приведенном выше примере использование символа "?", как в "Discount Amount" выше, помогает анализатору различать входные и выходные данные.</p>
41
<p>Тесты также должны включать проверки на отказы, например.</p>
41
<p>Тесты также должны включать проверки на отказы, например.</p>
42
<h2>Заключение</h2>
42
<h2>Заключение</h2>
43
<p>Микросервисы зависят от других сервисов и систем, что требует четкой спецификации интерфейсов и их аккуратное тестирование. Этого можно добиться с помощью описания поведения и интерфейсов, заданных с помощью тестов. С помощью BDD, функциональность сервисов описывается исполняемыми тестами, которые фокусируются<strong>на семантике операций, а не на синтаксисе</strong>. Автоматизация таких тестов обычно требует настройки заглушек других сервисов, поведение которых описываются их отдельными BDD-тестами.</p>
43
<p>Микросервисы зависят от других сервисов и систем, что требует четкой спецификации интерфейсов и их аккуратное тестирование. Этого можно добиться с помощью описания поведения и интерфейсов, заданных с помощью тестов. С помощью BDD, функциональность сервисов описывается исполняемыми тестами, которые фокусируются<strong>на семантике операций, а не на синтаксисе</strong>. Автоматизация таких тестов обычно требует настройки заглушек других сервисов, поведение которых описываются их отдельными BDD-тестами.</p>
44
<p>Интерфейсно-ориентированное проектирование - IOD, включает дополнительные обязательства сервиса: ограничение на использование ресурсов, пропускная способность и отчеты об ошибках. Вместе BDD и IOD помогают описать поведение сервиса, чтобы клиенты могли легко понять и положиться на него.</p>
44
<p>Интерфейсно-ориентированное проектирование - IOD, включает дополнительные обязательства сервиса: ограничение на использование ресурсов, пропускная способность и отчеты об ошибках. Вместе BDD и IOD помогают описать поведение сервиса, чтобы клиенты могли легко понять и положиться на него.</p>
45
<ol><li>BDD для микросервисов концентрируется на сотрудничестве триады - разработчика сервиса, разработчика клиента и тестировщика.</li>
45
<ol><li>BDD для микросервисов концентрируется на сотрудничестве триады - разработчика сервиса, разработчика клиента и тестировщика.</li>
46
<li>Создавайте четко-описанные соглашения для интерфейсов микросервисов, используя IOD.</li>
46
<li>Создавайте четко-описанные соглашения для интерфейсов микросервисов, используя IOD.</li>
47
<li>Микросервисы обычно требуют тестовые заглушки для ускорения тестирования.</li>
47
<li>Микросервисы обычно требуют тестовые заглушки для ускорения тестирования.</li>
48
<li>Тесты должны быть независимые.</li>
48
<li>Тесты должны быть независимые.</li>
49
<li>Проверяйте в тестах негативные сценарии.</li>
49
<li>Проверяйте в тестах негативные сценарии.</li>
50
</ol>
50
</ol>