Комментарии 4
Спасибо, интересно! Хоть и я язык немного вырвиглазный. Но спасибо, хоть не питон)
Вот у вас есть на входе update от тг, на выходе вызывается:
bot.send_message(msg.chat.id, "Привет!").await?;Почему бы для каждого состояния диалога не подготовить контекст, замокать bot.send_message и проверить что вы отправляете в тг обратно? Ну или, чтобы не мельчить, полностью сценарии так прогнать, получая от ваших хэндлеров ответ и отправляя в том же тесте новые запросы?
Хороший вопрос. Мокать bot.send_message напрямую вполне рабочий подход, но я осознанно пошёл в сторону black-box.
Дело вот в чём: чтобы замокать bot.send_message, нужно либо оборачивать бота в трейт, либо городить условную компиляцию. То есть менять прикладной код ради тестов. А я хотел, чтобы бот вообще не знал, что его тестируют. Тестируется ровно тот код, который поедет в прод. Без подмен, без trait-объектов, без #[cfg(test)] в бизнес-логике.
И ровно то, что вы описали («полностью сценарии прогнать, получая ответ и отправляя новые запросы») у меня именно так и работает. Отправил update, проверил ответ, отправил следующий. Полноценный диалог, только вместо Telegram API локальный HTTP-сервер. Бот думает, что общается с Telegram, и ведёт себя соответственно.
Ещё один момент: существующие подходы к тестированию teloxide-ботов (включая teloxide_tests) требовали глубокой связки с внутренностями фреймворка. Тесты получались хрупкими, по сути тестировали не бота, а свои моки. После очередного обновления teloxide половина тестов ломалась не потому что что-то реально сломалось, а потому что внутренний API поменялся.
Короче: я мокаю Telegram API, а не код бота.
У меня видимо в .net по-другому устроен инфраструктурный код: bot - это класс из сторонней библиотеки, который оборачивает все запросы к tg api и реализует интерфейс. Если замокать этот интерфейс и передать мок в мой код, то потом можно проверить, что он получал в send_message.
Саму реализацию bot не тестим, только бизнес-логику того, что у вас числится как handlers_tree. Причем по-моему это уже black-box, было бы неплохо еще каждый хэндлер отдельно покрыть тестами, но, с другой стороны, проверять, что уходит в tg пока достаточно)
Я понял. Тут немного по другому, есть библиотека и она к сожалению не поддерживает мок для bot'а! У вас это действительно реализовано лучше. Но имеем что имеем, я использую самую популярную библиотеку для Rust c 3 тысячами звезд.
Можно и нужно каждый хэндлер отдельно покрывать тестами, и это более менее нормально работает. В моем случае я уткнулся в проблему именно E2E теста, от первого сообщения боту до проверки всех возможных сценариев, и в особенности что бот правильно переключается из состояния в состояние.

Почему ваши тесты для Telegram-ботов работают неправильно (и как это исправить)