我正在尝试创建一个 pytest 文件来测试电报机器人的多个功能(启动和名称)。我设法单独测试每个函数并且它有效,但是当我尝试测试多个函数时,它显示错误:
PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped. You need to install a suitable plugin for your async framework.
即使我已经安装了提到的插件-pytest asyncio。
这是项目文件供参考
import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
task_list = {}
formatted_task_list = []
done_list = {}
formatted_done_list = []
user_name = {}
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
if user_id not in task_list:
task_list[user_id] = []
done_list[user_id] = []
user_name[user_id] = "Task"
await context.bot.send_message(chat_id=update.effective_chat.id, text="👋Hello! Welcome to Task List")
async def name(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
if user_id in task_list:
user_id = update.effective_user.id
user_name[user_id] = " ".join(context.args)
user_name[user_id] = f"<b>{user_name[user_id]}</b>"
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"Your list will be named {user_name[user_id]}. You're set!", parse_mode="HTML")
else:
await context.bot.send_message(chat_id=update.effective_chat.id, text="Type /start to start using this bot.")
def main():
application = ApplicationBuilder().token('My tokens').build()
start_handler = CommandHandler(['start', 'hello'], start)
name_handler = CommandHandler('name', name)
application.add_handler(start_handler)
application.add_handler(name_handler)
application.run_polling()
if __name__ == "__main__":
main()
这是我的pytest代码
import pytest
from unittest.mock import AsyncMock, patch
from project import start, view, add, name
# Mocks
class MockUser:
def __init__(self, id):
self.id = id
class MockChat:
def __init__(self, id):
self.id = id
class MockBot:
async def send_message(self, chat_id, text):
pass
# Test case
@pytest.mark.asyncio
@patch('project.task_list', {932872542: ['Example Task']})
@patch('project.done_list', {932872542: []})
@patch('project.user_name', {932872542: 'Task'})
async def test_start_function():
update_mock = AsyncMock()
context_mock = AsyncMock()
context_mock.bot = AsyncMock()
update_mock.effective_user = MockUser(932872542)
update_mock.effective_chat = MockChat(123)
update_mock.message.text = "/start"
await start(update_mock, context_mock)
context_mock.bot.send_message.assert_called_once_with(
chat_id=123,
text="👋Hello! Welcome to Task List")
async def test_name_function():
update_mock = AsyncMock()
context_mock = AsyncMock()
context_mock.bot = AsyncMock()
update_mock.effective_user = MockUser(932872542)
update_mock.effective_chat = MockChat(123)
update_mock.message.text = "/name New List"
context_mock.args = ["New", "List"]
await name(update_mock, context_mock)
context_mock.bot.send_message.assert_called_once_with(
chat_id=123,
text="Your list will be named <b>New List</b>. You're set!",
parse_mode="HTML",
)
if __name__ == "__main__":
pytest.main()
谢谢!
您的
test_name_function()
函数缺少 pytest.mark.asyncio
装饰器。这导致 pytest 跳过 test_name_function
测试。
像这样添加它:
@pytest.mark.asyncio
async def test_name_function():
请注意,您很可能还想包含其他函数装饰器:
@pytest.mark.asyncio
@patch('project.task_list', {932872542: ['Example Task']})
@patch('project.done_list', {932872542: []})
@patch('project.user_name', {932872542: 'Task'})
async def test_name_function():