BorisovAI
Все публикации
Новая функцияC--projects-bot-social-publisherClaude Code

Unit-тесты зелёные, а бот не работает: гонка условий в Telegram

Unit-тесты зелёные, а бот не работает: гонка условий в Telegram

Когда unit-тесты лгут: как я запустил систему доступа в реальном Telegram

bot-social-publisher выглядел как отличный проект для спринта. Полнофункциональный Telegram-бот с командами, памятью, интеграциями. Я предложил добавить управление доступом — чтобы владельцы чатов могли приватизировать разговоры с ботом. Звучит просто: только авторизованные пользователи видят ответы. Идеально для персональных AI-ассистентов или закрытых групп модерации.

Я развернул ChatManager — класс с методом is_allowed(), который проверяет разрешение пользователю писать в конкретный чат. Добавил миграцию SQLite для таблицы managed_chats, обвязал всё middleware’ами в aiogram, написал четыре команды: /manage add, /manage remove, /manage status, /manage list. Unit-тесты прошли с ликованием. pytest выдал зелёный статус. Документация? Позже, мол.

Потом наступил момент истины.

Запустил бота локально через python telegram_main.py. В личном чате отправил /manage add — чат добавился, режим приватности активировался. Отправил обычное сообщение — ответ пришёл. Открыл второй аккаунт, отправил то же — бот молчит. Отлично, система контроля работает!

Но не совсем.

Первая проблема вскрылась при быстрых командах подряд. aiogram работает асинхронно, как и aiosqlite. Получилась коварная гонка условий: middleware проверяет разрешения раньше, чем транзакция в БД успела закоммититься. Бот получает /manage add, начинает писать в таблицу, но собственная система контроля выполняет проверку за доли секунды до того, как данные туда попадут. На unit-тестах такое не видно — там всё выполняется последовательно.

Вторая проблема — SQLite и одновременные асинхронные обработчики. Один handler записывает изменение в БД, другой в это время проверяет состояние и видит старые данные, потому что commit() ещё не произошёл. Мне помогли явные транзакции и аккуратная расстановка await‘ов — гарантия того, что каждая операция завершится перед следующей.

Вот в чём разница между unit-тестами и интеграционными испытаниями: первые проверяют, что функция работает в идеальных условиях. Вторые отправляют реальное сообщение через серверы Telegram, пускают его через весь стек middleware, обрабатывают в handler’е, записывают в БД и возвращают результат. Тесты говорили: всё работает. Реальность показала: медленно и с условиями.

После боевых испытаний я заполнил полный чеклист: импорты класса, валидация миграции, проверка всех команд в живом Telegram, полный набор pytest, документация в docs/CHAT_MANAGEMENT.md с примерами архитектуры. Восемь пунктов — восемь потенциальных взрывов, которые благополучно не произошли.

Урок выучен: асинхронность и базы данных требуют больше, чем зелёные unit-тесты. Реальный Telegram и реальная асинхронность покажут то, что никогда не отловишь в тестовом окружении.

😄 Говорят, асинхронные баги в облаке GCP просто растворяются — поэтому их никто не находит.

Метаданные

Session ID:
grouped_C--projects-bot-social-publisher_20260209_1220
Branch:
main
Dev Joke
Что сказал Celery при деплое? «Не трогайте меня, я нестабилен»

Оцените материал

0/1000