Масштабирование по оси X - горизонтальное масштабирование
Масштабирование по оси Y - функциональная декомпозиция
Масштабирование по оси Z - разбиение данных
Масштабирование по оси X - горизонтальное масштабирование Масштабирование по оси Y - функциональная декомпозиция Масштабирование по оси Z - разбиение данных

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

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

Содержание

  • Что такое микросервисы

  • Это сложно!

  • Кто хочет, тот добьётся

  • Выводы

Что такое микросервисы

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

В своей книге «Микросервисы. Паттерны разработки и рефакторинга» Крис Ричардсон говорит о трех аспектах определения архитектуры микросервисов, подсказанных трехмерной моделью расширяемости Мартина Эббота и Майкла Фишера – кубом масштабирования. Он предполагает три способа масштабирования приложения:

  • Масштабирование по оси X или горизонтальное масштабирование – это выполнение многочисленных идентичных экземпляров приложения на фоне работы балансировщика нагрузки.

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

  • Масштабирование по оси Z или разбиение данных – масштабирование приложения на основе разбиения данных, при котором каждый экземпляр отвечает за подмножество данных.

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

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

Это сложно!

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

В то время как предложенная Майком Коном пирамида тестирования широко используется в качестве лучшей практики при построении стратегии тестирования микросервисов, ее реализация по-прежнему далека от идеала. Наиболее частая проблема возникает на этапе разработки теста – реализация соответствующего набора тестов в правильном месте. ✅

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

По отдельности все прекрасно, но окончательный результат дает только интеграционный тест

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

Заглушки – это прекрасно, но на них нельзя полагаться

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

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

Разрабатывать то, что надо, или разрабатывать как надо?

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

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

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

Я знаю, что пошло не так, но понятия не имею, где это случилось

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

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

Наша тестовая среда не является точной копией среды эксплуатации

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

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

Кто хочет, тот добьётся

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

Не отходить от основ

Несмотря на то, что мы должны осваивать новые инструменты и технологии, обеспечивая необходимую скорость поставки ПО, не следует отклоняться от основ. В книге Лизы Криспин и Джанет Грегори «Agile-тестирование» описана модификация квадрантов тестирования Брайана Мэрика, которая помогает классифицировать различные типы тестов.

 

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

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

Понять общую картину

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

  • Тестирование по оси Y – тестирование микросервисов согласно функциональной декомпозиции. Эти тесты обычно включают юнит-тесты, тесты компонентов, контрактное и интеграционное тестирование. Низкоуровневые тесты зависят от тестовых двойников (имитаций и заглушек), в то время как высокоуровневые тесты ближе к сквозному тестированию и обычно выполняются в интегрированной среде.

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

  • Тестирование по оси Z – тестирование стабильности поведения приложения по разделам данных. Данные тесты обычно заключаются в оценке способности приложения направлять запросы к соответствующему серверу, который содержит данные. Эти тесты позволяют получить представление о согласованности данных и соответствии требованиям SLA путем направления запросов разным наборам серверов.

Стараемся строить то, что надо

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

Низкоуровневые тесты стоят меньше

Эта идея должна внедриться в ДНК команд – низкоуровневые тесты обходятся дешевле и сокращают время поставки. Результаты данных тестов могут показать проблемы в приложении на уровне функции/юнита/компонента, следовательно, эти проблемы легче исправить.

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

Проверить код недостаточно

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

Юнит-тесты должны быть более функциональными

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

Используйте заглушки, но сделайте их надежными

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

  • Количество вариантов бизнес-сценариев становится огромным.

  • Отсутствие процесса оптимизации и проверки заглушек на соответствие реальным системам.

Командам следует сосредоточиться на внедрении инновационного решения для заглушек, которое сочетало бы в себе стратегии статических и динамических заглушек. Также необходимо использовать автоматическую систему, которая может проверять и менять (или по крайней мере выделять!) устаревшие заглушки. Этот сценарий является кандидатом для контрактного тестирования – процесса, который дает уверенность в бесшовной интеграции и обеспечивает надежность заглушек.

Планируйте автоматизацию – не допускайте ее органического роста

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

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

Знать, что пошло не так и где

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

Дело в обсуждении и взаимодействии

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

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

Развертывание среды нажатием кнопки

Масштабирование по оси X куба масштабирования предполагает возможность горизонтального масштабирования – одного из важнейших аспектов разработки микросервиса. Большинство современных микросервисных систем представляют собой контейнерные приложения.

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

«Путешествие – само по себе личность, двух одинаковых не бывает» – Джон Стейнбек

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

Наблюдаемость – ключ к успеху: наблюдайте, выявляйте, действуйте. Это путешествие приближает систему к совершенству! Надеюсь, статья вам понравилась. Успехов в тестировании!  ????

Другие интересные статьи в нашем блоге (от переводчика):

  1. Когда стоит выбирать микросервисы

  2. Property-based тестирование с QuickCheck

  3. Взгляд на легаси со стороны «пассажира»

  4. Антирегрессионное тестирование – минимизируйте затраты

Комментарии (1)


  1. otchgol
    17.01.2022 19:28
    +5

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

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