telegym

Load testing for Telegram bots โ€” drop-in mock of the Bot API plus a k6 extension for virtual-user scenarios. Works with any bot, any language.

CI Go Reference Go Report Card Supported Bot API Latest Release License: MIT

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