【发布时间】:2021-04-19 08:23:03
【问题描述】:
我正在尝试在 Python 3.8 下使用 Tortoise ORM 在 FastAPI 中编写一些异步测试,但我不断收到相同的错误(见最后)。过去几天我一直在尝试解决这个问题,但不知何故,我最近创建测试的所有努力都没有成功。
我正在关注这个fastapi docs 和tortoise docs。
main.py
# UserPy is a pydantic model
@app.post('/testpost')
async def world(user: UserPy) -> UserPy:
await User.create(**user.dict())
# Just returns the user model
return user
simple_test.py
from fastapi.testclient import TestClient
from httpx import AsyncClient
@pytest.fixture
def client1():
with TestClient(app) as tc:
yield tc
@pytest.fixture
def client2():
initializer(DATABASE_MODELS, DATABASE_URL)
with TestClient(app) as tc:
yield tc
finalizer()
@pytest.fixture
def event_loop(client2): # Been using client1 and client2 on this
yield client2.task.get_loop()
# The test
@pytest.mark.asyncio
def test_testpost(client2, event_loop):
name, age = ['sam', 99]
data = json.dumps(dict(username=name, age=age))
res = client2.post('/testpost', data=data)
assert res.status_code == 200
# Sample query
async def getx(id):
return await User.get(pk=id)
x = event_loop.run_until_complete(getx(123))
assert x.id == 123
# end of code
我的错误取决于我使用的是client1 还是client2
使用client1 错误
RuntimeError: Task <Task pending name='Task-9' coro=<TestClient.wait_shutdown() running at <my virtualenv path>/site-packages/starlette/testclient.py:487> cb=[_run_until_complete_cb() at /usr/lib/python3.8/asyncio/base_events.py:184]> got Future <Future pending> attached to a different loop
使用client2 错误
asyncpg.exceptions.ObjectInUseError: cannot drop the currently open database
哦,我也尝试过使用httpx.AsyncClient,但仍然没有成功(还有更多错误)。任何想法,因为我没有自己的想法。
【问题讨论】:
-
我遇到了同样的问题并解决了它,放弃了不使用 asyncio 测试。基本上我的代码和你一样,只是测试没有
@pytest.mark.asyncio标签。为了使用httpx,可能值得研究event_loop的分享,但对我来说这需要太多时间和精力 -
时间和精力已确认。我确实试图更深入地研究那个 event_loop,它给我带来的只是我的前任会嫉妒的痛苦。所以你完全放弃了所有形式的异步测试?之后你做了什么?
-
我同步测试端点。其余的代码都是一样的,只是为了测试上的
asyncio注解 -
刚刚在乌龟回购中发现了一个类似的问题here。看起来这种情况不会很快消失。
-
您能提供一个最小的可运行示例吗?缺少一些东西(UserPy、初始化器、终结器),这使得它很难重现。
标签: python python-3.8 fastapi tortoise-orm