Добавьте больше достоверности в свои тесты

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

Ресурсный оптимизм

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

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

Результатом ресурсного оптимизма может быть нестабильность при выполнении теста, другими словами, тест показывает результат pass или fail при выполнении на той же кодовой базе.

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

AWS ресурсы, такие как S3 сегменты или sqs очереди, являются внешними ресурсами, и поэтому их следует рассматривать как сомнительные для оптимизма.

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

Представляем МОТО

Moto — это библиотека с открытым исходным кодом, которая обеспечивает простую абстракцию встроенной в Python mock-библиотеки модульных тестов.

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

Руки вверх

Давайте посмотрим на простой класс Python:

Класс Project определяет состояние проекта.

При инициализации он создает два ресурса: один — это ведро s3; другой — очередь SQS, которая также генерирует клиентский объект для AWS SQS и s3 с использованием библиотеки boto3.

Кроме того, у него есть состояние, которое выражается в виде UUID.

Когда вызывается save, состояние изменяется, и ввод message сохраняется в сегменте s3.

При вызове restore вызывается ранее сохраненное сообщение из s3, а затем отправляется уведомление в очередь SQS.

После этого сообщение возвращается во внешний контекст.

Напишем простой модульный тест:

Этот тест ужасен, так как он зависит от внешних ресурсов AWS, но благодаря moto его можно легко улучшить, написав всего три строки кода (ленивые программисты это оценят :D).

Во-первых, давайте установим moto из PyPI:

pip install moto

Теперь давайте используем moto в нашем тестовом коде:

Сначала мы импортируем s3_mock и sqs_mock из moto..

Эти два decorators, и они могут украшать либо функции, либо классы, создавая макет всех вызовов обработки ресурсов AWS в декорированном блоке кода.

Теперь мы можем decorate класс TestMyAws и во всех последующих блоках кода AWS будет имитироваться.

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

Запустим тест:

python -m unittest test/test_basic.py

Выход:

.
----------------------------------------------------------------------
Ran 1 test in 1.074s
OK

Последнее примечание

В нашем тестовом коде инициализации мы хотим максимально возможной изоляции.

Однако это не всегда относится к более надежным тестам, интеграционным тестам, тестам API, регрессионным тестам или E2E.

Иногда нам нужно использовать реальный ресурс или использовать фиктивные серверы.

Moto позволяет писать стабильные тесты и быть более кратким в тестовом коде.

Спасибо за прочтение.