Telegram app logo is seen in this illustration taken, Aug 27, 2024.
Image: Reuters file
Sometimes the problem isn’t in your test code — it’s in how Telegram handles updates.
If your bot is running locally in polling mode, and your test also tries to read updates — nothing will break… but nothing will work either.
Let me explain what happened — and why this behavior is easy to overlook when you're just starting to test Telegram bots as myself.
The Problem
I was writing a test for the /start
command using pytest
.
The bot was running locally, the token was valid, everything looked fine — but the test was just...waiting.
Turns out, the issue wasn’t in the code — it was in the way Telegram’s getUpdates
API works.
Here’s what was really going on:
My bot was running with .run_polling()
, which continuously polls getUpdates
in the background.
My test was also calling getUpdates
manually, expecting to retrieve the /start
command from a real Telegram chat.
The result? A hidden conflict.
Telegram only allows one active consumer of updates.
So when the bot is running, it “eats” all updates — and the test sees nothing.
🛠️ How to Fix It
Since you can’t simulate a user sending /start
directly through the Telegram API (that’s forbidden), here are two reliable alternatives:
Option 1: Manual Trigger + Stored Log Verification
Best for CI or webhook-based bots.
You manually send /start
from Telegram.
Your bot processes it and logs the result.
Your test waits briefly, then checks the log file or database to confirm the expected output.
Option 2: Simulate Telegram webhook with a fake payload
A fully automated way using requests.post()
or similar to mock a real Telegram update:
You run your bot in webhook mode (instead of polling).
Telegram would normally send POST requests to your webhook URL (e.g. https://abc123.ngrok-free.app/webhook
)
Instead, your test simulates this POST request using your own payload.
Your Flask or FastAPI app receives it and behaves as if it came from Telegram.
But why do I need Flask or FastAPI at all?
When using webhooks, Telegram sends updates to your bot as HTTP POST requests.
To receive them — you need a web server.
That’s where Flask or FastAPI comes in.
They expose an endpoint like /webhook
that can receive and process Telegram’s payloads.
Webhook flow:
- Telegram sends an update:
POST
https://yourdomain.com/webhook
- Flask/FastAPI receives it and hands it over to python-telegram-bot
- Your handler function is called just like in polling mode
Without this, your bot simply won’t work in webhook mode — and you won’t be able to test real-world flows in CI/CD.
Testing Telegram bots has its nuances and bottlenecks, and this one was a surprise for me too.
But the deeper you go — the more power you unlock.
This case alone pushed me to explore better testing strategies and architect a more production-like setup, even for test automation.
Would you be interested in more deep-dives on Telegram bot testing?
Let me know in the comments or drop a DM — I’m currently building a courses on this topic using Pytest, Playwright, and Cypress.
Top comments (0)