Тестирование приложения 🧪#
Вы создали приложение FastStream с двумя независимыми сервисами (app.py и app2.py), которые обрабатывают сообщения с помощью Pydantic и строковые данные! 🎉 Теперь пора убедиться, что они работают правильно. В этом разделе мы научимся тестировать оба сервиса с помощью TestRabbitBroker, который эмулирует RabbitMQ в памяти, без необходимости запускать реальный брокер. Мы также проверим вызовы обработчиков, используя автоматическое мокирование. Это быстро, удобно и идеально для новичков! 😊 Готовы проверить ваш код? Погнали! 🚀
Зачем тестировать FastStream? 🤔#
Тестирование позволяет убедиться, что ваше приложение обрабатывает сообщения как ожидалось. С FastStream тестирование особенно удобно, потому что:
- Эмуляция брокера 🔄:
TestRabbitBrokerимитирует RabbitMQ, не требуя реального подключения, что ускоряет тесты. - Проверка валидации ✅: Мы можем убедиться, что Pydantic правильно обрабатывает корректные и некорректные сообщения в
app.py. - Мокирование 🤖:
TestRabbitBrokerавтоматически мокирует обработчики, позволяя проверить, какие данные они получают.
Мы напишем тесты для сервисов из предыдущего раздела: app.py обрабатывает сообщения с полями username и message, передавая их из input-queue в output-queue, а app2.py обрабатывает строковые сообщения из final-queue.
Шаг 1: Установка pytest 📦#
Для тестирования будем использовать pytest и pytest-asyncio. Установите их в вашу виртуальную среду (если ещё не установлено):
Проверьте установку:
Вы должны увидеть версию, например, pytest 8.x.x. Теперь мы готовы писать тесты! 💻
Шаг 2: Создание тестов ✍️#
Поскольку у нас два независимых сервиса, мы создадим два тестовых файла в папке faststream-tutorial:
test_app1.pyдля тестированияapp.py.test_app2.pyдля тестированияapp2.py.
Добавьте код в test_app1.py:
Добавьте код в test_app2.py:
Что здесь происходит? 🔍
TestRabbitBroker🔄: Контекстный менеджер, эмулирующий RabbitMQ в памяти, без подключения к реальному брокеру.async with TestRabbitBroker(broker)вызываетbroker.connect()иbroker.close(), что идеально для тестирования без реальных подписчиков. Параметрwith_realпозволяет переключаться на реальный брокер, если установлена переменная окруженияTEST_BROKER_WITH_REAL=1.- Мокирование обработчиков 🤖:
TestRabbitBrokerавтоматически мокирует обработчики (handle_message,check_result,final_result), позволяя проверить, какие данные они получают через.mock.assert_called_once_with(). test_correct_message_app1✅: Отправляет корректное сообщениеUserMessageвinput-queue, проверяет, что:handle_messageвызван с входным сообщением в виде словаря ({"username": "Alice", "message": "Hello"}), так как FastStream сериализуетUserMessage.check_resultвызван с обработанным сообщением ({"username": "Alice", "message": "HELLO"}) изoutput-queue.
test_correct_message_app2✅: Отправляет строковое сообщение вfinal-queue, проверяет, чтоfinal_resultвызван с"Привет, FastStream!".test_invalid_message🚫: Отправляет некорректное сообщение (сwrong_field) вinput-queueи проверяет, что Pydantic выбросил ошибку валидации.pytest.mark.asyncio⚡: Позволяет использоватьasync/awaitв тестах.
Напоминание 📝: Контекстный менеджер TestRabbitBroker вызывает только broker.connect() и broker.close(), что идеально для тестирования. Для реального приложения с подписчиками используется broker.start() (как в faststream run app:app).
Шаг 3: Запуск тестов ▶️#
Убедитесь, что файлы app.py, app2.py, test_app1.py и test_app2.py находятся в папке faststream-tutorial. Запустите тесты:
Вы увидите вывод, например:
============================= test session starts ==============================
test_app1.py::test_correct_message_app1 PASSED [ 33%]
test_app1.py::test_invalid_message PASSED [ 66%]
test_app2.py::test_correct_message_app2 PASSED [100%]
=========================== 3 passed in 0.XXs ==============================
Все тесты прошли успешно! 🎉 Это подтверждает, что:
- В
app.pyкорректное сообщение обрабатывается, передается вoutput-queueс измененнымmessage, и валидация Pydantic работает. - В
app2.pyстроковое сообщение изfinal-queueобрабатывается корректно.
Шаг 4: Разбираемся с TestRabbitBroker и мокированием 🛠️#
TestRabbitBroker делает тестирование мощным и гибким:
- Эмуляция очередей 🗄️:
TestRabbitBrokerобрабатывает сообщения в памяти, не требуя реального RabbitMQ. - Автоматическое мокирование 🔎: Подписчики автоматически мокируются, позволяя проверить вызовы обработчиков через
.mock.assert_called_once_with(). - Поддержка валидации 🛡️: Pydantic работает так же, как в реальном приложении, обеспечивая проверку данных в
app.py. - Тестирование с реальным брокером 🔗: Переменная
WITH_REAL(устанавливается через окружениеTEST_BROKER_WITH_REAL=1) позволяет переключитьTestRabbitBrokerна использование реального брокера вместо эмуляции. Это полезно для интеграционного тестирования, когда нужно проверить взаимодействие с настоящим RabbitMQ, например, для подтверждения корректной работы с очередями или сетевыми настройками. - Тестирование независимых сервисов 🤝: Разделение тестов на
test_app1.pyиtest_app2.pyотражает независимость сервисов.
Этот подход, вдохновленный примерами FastStream, позволяет тестировать сложные сценарии с минимальным кодом.
Шаг 5: Практическое задание 📚#
Закрепите знания с помощью заданий:
- В
test_app1.pyдобавьте тест, который проверяет, чтоmessageвoutput-queueвсегда в верхнем регистре (например,HELLOдля входногоHello). - В
test_app1.pyсоздайте тест для проверки обработки сообщения с пустой строкой в полеmessage, если вы добавилиmin_length=1в модельUserMessageвapp.py. - (Дополнительно) В
test_app2.pyнапишите тест, который проверяет, чтоfinal_resultвызывается только один раз для одного сообщения вfinal-queue.
Что дальше? 🗺️#
Вы научились тестировать FastStream-приложения с использованием TestRabbitBroker и автоматического мокирования! 🎉 Это важный навык для создания надежных микросервисов. В следующем разделе мы узнаем, как генерировать красивую документацию в формате AsyncAPI, чтобы делиться спецификацией вашего приложения. Перейдите к Генерация документации, чтобы освоить этот процесс.
Если у вас есть идеи, вопросы или нужна помощь, загляните в официальную документацию FastStream, пишите в Telegram или Discord. Продолжайте тестировать и кодить! 🚀