我正在学习 TDD fastapi、docker 和 pytest 课程的第一部分。我遇到了一个奇怪的问题,需要您的帮助。
当我创建第一个使用 torotoise 的测试时,它工作正常,将记录添加到数据库,并从 fastapi 获取它,没有任何问题。
当我添加另一个测试(添加然后读取记录的测试)时,我收到此错误:
tortoise.exceptions.OperationalError: relation "textsummery" does not exist
(请忽略“摘要”一词中的拼写错误,它一开始是一个错误,但我用它来强迫自己不要盲目地复制粘贴所有内容)
如果我删除第一个测试,这个错误现在就消失了,并且测试顺利进行
有什么理由不使用已经创建的表吗?
代码:
# C:\src\tdd-fastapi\project\test\conftest.py
@pytest.fixture(scope="module")
def test_app_with_db():
# set up
app = create_applications()
app.dependency_overrides[get_settings] = get_settings_override
register_tortoise(
app,
db_url=os.environ.get("DATABASE_TEST_URL"),
modules={"models": ["app.models.tortoise"]},
generate_schemas=True,
add_exception_handlers=True,
)
还有
# C:\src\tdd-fastapi\project\test\test_summeries.py
def test_create_summery(test_app_with_db):
response = test_app_with_db.post("/summeries/", data=json.dumps({"url": "https://foo.bar"}))
assert response.status_code == 201
assert response.json()["url"] == "https://foo.bar"
assert response.json()["id"] != 0
# ...
def test_read_summery(test_app_with_db):
response = test_app_with_db.post("/summeries/", data=json.dumps({"url": "https://foo.bar"}))
assert response.status_code == 201
assert response.json()["url"] == "https://foo.bar"
assert response.json()["id"] != 0
summery_id = response.json()["id"]
response = test_app_with_db.get(f"/summeries/{summery_id}/")
assert response.status_code == 200
response_dict = response.json()
assert response_dict["id"] == summery_id
assert response_dict["url"] == "https://foo.bar"
assert response_dict["summery"]
assert response_dict["created_at"]
根据评论建议,我添加了 torotoise 和 testconf
from tortoise import fields, models
from tortoise.contrib.pydantic import pydantic_model_creator
# C:\src\tdd-fastapi\project\app\models\tortoise.py
class TextSummery(models.Model):
url = fields.TextField()
summery = fields.TextField()
created_at = fields.DatetimeField(auto_now_add=True)
updated_at = fields.DatetimeField(auto_now=True)
def __str__(self):
return self.url
SummerySchema = pydantic_model_creator(TextSummery)
还有
# C:\src\tdd-fastapi\project\test\conftest.py
import os
import pytest
from starlette.testclient import TestClient
from app.main import create_applications
from app.config import get_settings, Settings
from tortoise.contrib.fastapi import register_tortoise
def get_settings_override() -> Settings:
return Settings(testing=1, database_url=os.environ.get('DATABASE_TEST_URL'))
@pytest.fixture(scope='module')
def test_app():
# setup
app = create_applications()
app.dependency_overrides[get_settings] = get_settings_override
with TestClient(app) as test_client:
yield test_client
@pytest.fixture(scope="module")
def test_app_with_db():
# set up
app = create_applications()
app.dependency_overrides[get_settings] = get_settings_override
register_tortoise(
app,
db_url=os.environ.get("DATABASE_TEST_URL"),
modules={"models": ["app.models.tortoise"]},
generate_schemas=True,
add_exception_handlers=True,
)
with TestClient(app) as test_client:
# testing
yield test_client
# tear down
找到了! 问题不在我包含的任何文件中,而是在 main.py 中
在创建应用程序中我有以下代码:
def create_applications() -> FastAPI:
application = FastAPI()
register_tortoise(
application,
db_url = os.environ.get("DATABASE_URL"),
modules = {"models": ["app.models.tortoise"]},
generate_schemas=False, # updated
add_exception_handlers = True
)
application.include_router(ping.router)
application.include_router(summeries.router, prefix="/summeries", tags=['summeries'])
return application
这是课程的前一部分,我忘了删除它。 我不确定为什么它只影响第二次测试,但我有一个应该处理它的函数,称为 init_db。删除register_tortoise后,所有测试都按预期工作。