A testing framework for Aiogram 3.x Telegram bots
Project description
Aiogram Test Framework
A testing framework for Aiogram 3.x Telegram bots that provides:
- Mocking the Telegram Bot API
- Capturing all outgoing bot requests
- Simulating user interactions
- Testing handlers with full middleware chain
Installation
pip install aiogram-test-framework
Quick Start
import pytest
from aiogram import Bot, Dispatcher
from aiogram_test_framework import AsyncBotTestMixin
def setup_dispatcher(bot: Bot, dispatcher: Dispatcher) -> None:
"""Configure dispatcher with middlewares and handlers."""
# Your setup code here
pass
class TestMyHandler(AsyncBotTestMixin):
@pytest.fixture(autouse=True)
async def setup(self):
self.client = await self.setup_client(
setup_dispatcher_func=setup_dispatcher,
)
yield
await self.client.close()
self.reset_factories()
async def test_start_command(self):
user = self.client.create_user()
await user.send_command("start")
assert user.has_received_message_containing("Welcome")
Components
TestClient
High-level test client for interacting with an Aiogram bot.
from aiogram_test_framework import TestClient
# Create client
client = await TestClient.create(
bot_token="123456:ABC-DEF",
bot_id=123456,
bot_username="test_bot",
bot_first_name="Test Bot",
setup_dispatcher_func=setup_dispatcher,
)
# Create users and interact
user = client.create_user()
await user.send_command("start")
assert user.has_received_message_containing("Welcome")
# Close when done
await client.close()
MockBot
A mock Bot that captures all API requests for testing.
from aiogram_test_framework import MockBot, RequestCapture
capture = RequestCapture()
bot = MockBot(
capture=capture,
token="123456:ABC-DEF",
bot_id=123456,
bot_username="test_bot",
bot_first_name="Test Bot",
)
# Use bot in tests...
await bot.send_message(chat_id=123, text="Hello")
# Check captured requests
messages = capture.get_sent_messages()
assert len(messages) == 1
assert messages[0].text == "Hello"
RequestCapture
Captures and stores all requests made by the bot to the Telegram API.
from aiogram_test_framework import RequestCapture, RequestType
capture = RequestCapture()
# After bot makes requests...
messages = capture.get_sent_messages()
messages = capture.get_sent_messages(chat_id=12345) # Filter by chat
edited = capture.get_edited_messages()
deleted = capture.get_deleted_messages()
callbacks = capture.get_callback_answers()
dice_sends = capture.get_dice_sends()
# Get last message
last = capture.get_last_message()
last_in_chat = capture.get_last_message(chat_id=12345)
# Check content
has_welcome = capture.has_message_containing("Welcome")
has_welcome = capture.has_message_containing("Welcome", chat_id=12345)
# Get by type
all_sends = capture.get_by_type(RequestType.SEND_MESSAGE)
count = capture.count_by_type(RequestType.SEND_MESSAGE)
# Clear for next test
capture.clear()
TestUser
Represents a simulated Telegram user that can interact with the bot.
# Create via client
user = client.create_user(user_id=12345, first_name="John")
# Send messages/commands
responses = await user.send_message("Hello bot")
responses = await user.send_command("start")
responses = await user.send_command("start", args="referral_code")
# Click inline buttons
responses = await user.click_button("callback_data")
# Check responses
messages = user.get_sent_messages()
last = user.get_last_message()
has_welcome = user.has_received_message_containing("Welcome")
Factories
The framework provides factories for creating mock Telegram objects:
UserFactory- Create mock User objectsChatFactory- Create mock Chat objectsMessageFactory- Create mock Message objectsCallbackQueryFactory- Create mock CallbackQuery objectsUpdateFactory- Create mock Update objectsKeyboardFactory- Create mock keyboard markups
from aiogram_test_framework import UserFactory, MessageFactory
# Create user
user = UserFactory.create(
user_id=12345,
first_name="John",
username="johndoe",
)
# Create message
message = MessageFactory.create(
text="Hello!",
from_user=user,
)
# Create command
command = MessageFactory.create_command(
command="start",
from_user=user,
args="ref123",
)
Usage with Different Test Frameworks
pytest
import pytest
from aiogram_test_framework import AsyncBotTestMixin
class TestMyHandler(AsyncBotTestMixin):
@pytest.fixture(autouse=True)
async def setup(self):
self.client = await self.setup_client(
setup_dispatcher_func=setup_dispatcher,
)
yield
await self.client.close()
self.reset_factories()
async def test_start_command(self):
user = self.client.create_user()
await user.send_command("start")
assert user.has_received_message_containing("Welcome")
unittest
import asyncio
import unittest
from aiogram_test_framework import AsyncBotTestMixin
class TestMyHandler(unittest.TestCase, AsyncBotTestMixin):
def setUp(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
self.client = self.loop.run_until_complete(
self.setup_client(setup_dispatcher_func=setup_dispatcher)
)
def tearDown(self):
if hasattr(self, 'client') and self.client:
self.loop.run_until_complete(self.client.close())
self.reset_factories()
self.loop.close()
def test_start_command(self):
async def run_test():
user = self.client.create_user()
await user.send_command("start")
assert user.has_received_message_containing("Welcome")
self.loop.run_until_complete(run_test())
Django
from asgiref.sync import async_to_sync
from django.test import TransactionTestCase
from aiogram_test_framework import AsyncBotTestMixin
class TestMyHandler(TransactionTestCase, AsyncBotTestMixin):
def setUp(self) -> None:
async_to_sync(self._async_setup)()
def tearDown(self) -> None:
async_to_sync(self._async_teardown)()
async def _async_setup(self) -> None:
self.client = await self.setup_client(
setup_dispatcher_func=setup_dispatcher,
)
async def _async_teardown(self) -> None:
await self.client.close()
self.reset_factories()
async def test_start_command(self) -> None:
user = self.client.create_user()
await user.send_command("start")
assert user.has_received_message_containing("Welcome")
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiogram_test_framework-1.0.1.tar.gz.
File metadata
- Download URL: aiogram_test_framework-1.0.1.tar.gz
- Upload date:
- Size: 26.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce880bdb06fb1bbe89de8919e1fd687c8be0cb8c299f23829cb9fe73e9f7caf9
|
|
| MD5 |
20c1e03c547598826911940ae1c1582c
|
|
| BLAKE2b-256 |
d92107fa73fb6a042dd6d082698bba4ec418d11d171460fd0985a093a18f1db3
|
File details
Details for the file aiogram_test_framework-1.0.1-py3-none-any.whl.
File metadata
- Download URL: aiogram_test_framework-1.0.1-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd4c8e55554515aaf08f6c91ee033ce5eb1fcd39b9f103c61f5c2b3b03b5b2c4
|
|
| MD5 |
4176e027c7a090bb6ed9af28a4921304
|
|
| BLAKE2b-256 |
7451781cb56e2c3ea16ebb44e56e5116ef32d90f02b29d3441f97a663f0b7f43
|