telegram bot python 的 pytest 本身不支持异步 def 函数

问题描述 投票:0回答:1

我正在尝试创建一个 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()

谢谢!

python pytest python-telegram-bot python-unittest.mock pytest-asyncio
1个回答
0
投票

您的

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():
© www.soinside.com 2019 - 2024. All rights reserved.