Why
vs telegram-test-api
Node-based mock is great for functional smoke tests, but not designed for thousands of concurrent virtual users.
vs Test DC
Real Telegram infrastructure with Telethon / Pyrogram is accurate but expensive โ each VU is a real MTProto session, throttled above a few hundred clients.
vs raw k6
k6 is the industry standard for load, but it speaks HTTP, not Bot API. telegym bridges the gap with an xk6 extension.
Architecture
k6 scenario โโโบ xk6-telegym โโโบ /debug/inject/update โโโบ telegym-mock
โ
โผ
POST <bot_webhook_url>
โ
โผ
your bot
โ
โผ
POST telegym-mock/bot<token>/sendMessage
โ
โผ
stored in telegym-mock.botMessages
โ
โผ
xk6.awaitButton โโโ GET /debug/botMessages
Quickstart
Three commands to build and smoke-test the full stack against the bundled echobot:
# Optional one-time setup: copies .env.example -> .env and pre-fetches modules.
make init
# Build the mock, proxy, demo echobot, and a custom k6 with the xk6-telegym
# extension. The k6 build takes ~13s the first time.
make build build-examples
# Smoke test the full stack against the bundled echobot example
./examples/echobot/run.sh
# Output:
# checks_total.......: 10440 258.85/s
# checks_succeeded...: 100.00% 10440 out of 10440
# โ welcome arrived
# โ welcome under 500ms
Point your own bot at the mock โ then drive it manually in a browser, or with k6, or even from real Telegram:
# Start the mock and your bot (separate terminals)
./bin/telegym-mock
TELEGRAM_API_URL=http://localhost:5678 \
TELEGRAM_TOKEN=1234567890:telegym_default_mock_token_xxxxxxxx \
./your-bot # bot calls setWebhook automatically
# Then pick a driver:
open http://localhost:5678/debug/chat # manual click-around in the browser
./bin/k6 run path/to/your-scenario.js # load test (use ./bin/k6, not `brew install k6` โ the bundled binary has the xk6-telegym extension)
make proxy-up # real Telegram client โ mock (needs PROXY_TOKEN + MOCK_BOT_TOKEN)
Scenario API
JS scenarios import the extension as k6/x/telegym and get a default export exposing newUser():
import tg from 'k6/x/telegym';
const u = tg.newUser(0); // 0 = auto-allocate chat ID per VU
u.send('/start'); // inject a text message
const m = u.awaitText('^Welcome', 5); // wait up to 5s for matching reply
u.click('age_verify'); // inject a callback query
What's in the box
- Mock Bot API server โ all 176 methods accepted, 15 with real side effects, the rest dispatched via the official spec.
- xk6 extension โ virtual Telegram users from k6 scenarios with
send,click,awaitText,findButton. - User pools โ two-phase scenarios (register-then-replay) via NDJSON files, with
TAG/OFFSET/LIMIT/SHUFFLEenv knobs. - HTMX debug chat โ browser UI for manual testing, served by the mock itself, no real Telegram.
- Real-Telegram relay (
telegym-proxy) โ drive the bot-under-test from a real Telegram client through a throwaway proxy bot. - Metrics & dashboards โ Prometheus + Grafana stack with a pre-provisioned dashboard correlating k6 load and mock-side latency.