簡體   English   中英

在夾具中包含代碼后,帶有異步的 pytest 中的 AttributeError

[英]AttributeError in pytest with asyncio after include code in fixtures

我需要測試我的電報機器人。 為此,我需要創建客戶端用戶來詢問我的機器人。 我找到了可以做到這一點的Telethon圖書館。 首先,我編寫了一個代碼示例以確保授權和連接正常工作,並向自己發送測試消息(省略導入):

api_id = int(os.getenv("TELEGRAM_APP_ID"))
api_hash = os.getenv("TELEGRAM_APP_HASH")
session_str = os.getenv("TELETHON_SESSION")

async def main():
    client = TelegramClient(
        StringSession(session_str), api_id, api_hash,
        sequential_updates=True
    )
    await client.connect()
    async with client.conversation("@someuser") as conv:
        await conv.send_message('Hey, what is your name?')


if __name__ == "__main__":
    asyncio.run(main())

@someuser(我)成功接收消息。 好的,現在我根據上面的代碼使用夾具創建一個測試:

api_id = int(os.getenv("TELEGRAM_APP_ID"))
api_hash = os.getenv("TELEGRAM_APP_HASH")
session_str = os.getenv("TELETHON_SESSION")

@pytest.fixture(scope="session")
async def client():
    client = TelegramClient(
        StringSession(session_str), api_id, api_hash,
        sequential_updates=True
    )
    await client.connect()
    yield client
    await client.disconnect()


@pytest.mark.asyncio
async def test_start(client: TelegramClient):
    async with client.conversation("@someuser") as conv:
        await conv.send_message("Hey, what is your name?")

運行pytest后收到錯誤:

AttributeError: 'async_generator' object has no attribute 'conversation'

似乎client對象在“錯誤”條件下從client夾具返回。 這是print(dir(client))

['__aiter__', '__anext__', '__class__', '__class_getitem__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'aclose', 'ag_await', 'ag_code', 'ag_frame', 'ag_running', 'asend', 'athrow']

我在哪里從夾具中的生成器中釋放“正確”的客戶端對象?

我寧願使用anyio而不是pytest-asyncio

  • pip install anyio

嘗試這個:

import pytest

@pytest.fixture(scope="session")
def anyio_backend():
    return "asyncio"

@pytest.fixture(scope="session")
async def conv():
    client = TelegramClient(
        StringSession(session_str), api_id, api_hash,
        sequential_updates=True
    )
    await client.connect()
    async with client.conversation("@someuser") as conv:
        yield conv

@pytest.mark.anyio
async def test_start(conv):
    await conv.send_message("Hey, what is your name?")

根據文檔https://pypi.org/project/pytest-asyncio/#async-fixtures在異步夾具中使用@pytest_asyncio.fixture裝飾器。

像這樣:

import pytest_asyncio

@pytest_asyncio.fixture(scope="session")
async def client():
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM