gpt4 book ai didi

python - 如何使用 pytest、fastapi 和 tortoise-orm 回滚每个测试?

转载 作者:行者123 更新时间:2023-12-04 16:44:42 27 4
gpt4 key购买 nike

我正在为 crud 编写单元测试,我使用的框架是 FastAPI,ORM 是乌龟,测试模块是 pytest。
我有这个配置文件:

import os

import pytest
from starlette.testclient import TestClient
from tortoise.contrib.fastapi import register_tortoise

from app.config import Settings, get_settings
from app.main import create_application


def get_settings_override():
return Settings(
testing=1, database_url=os.environ.get("DATABASE_TEST_URL")
)

@pytest.fixture(scope="module")
def test_app_with_db():
# set up
app = create_application()
app.dependency_overrides[get_settings] = get_settings_override

# Link with DB for testing
register_tortoise(
app,
db_url=os.environ.get("DATABASE_TEST_URL"),
modules={"models": ["app.infra.postgres.models"]},
generate_schemas=True,
add_exception_handlers=True,
)
with TestClient(app) as test_client:

# testing
yield test_client

# tear down
另外,我有这些测试,第一个创建了一个新的载体。第二个,创建一个承运人,然后在数据库中搜索所有现有的承运人。
import json
from app.infra.postgres.crud.cft import cft as pg_cft
from app.services.cft import CFTService

cft_crud = CFTService(pg_cft)

PREFIX = "/api/cft/"


def test_create_carrier(test_app_with_db):
response = test_app_with_db.post(
f"{PREFIX}",
data=json.dumps(
{
"broker_id": 1,
"carrier_id": 1,
"lower_limit": 10,
"upper_limit": 100,
"fee": 50,
"is_active": True,
}
),
)
assert response.status_code == 201
assert type(response.json()["id"]) == int


def test_get_carriers(test_app_with_db):
response = test_app_with_db.post(
f"{PREFIX}",
data=json.dumps(
{
"broker_id": 1,
"carrier_id": 1,
"lower_limit": 10,
"upper_limit": 100,
"fee": 50,
"is_active": True,
}
),
)
summary_id = response.json()["id"]

response = test_app_with_db.get(f"{PREFIX}")
assert response.status_code == 200

response_list = response.json()

assert (
len(list(filter(lambda d: d["id"] == summary_id, response_list))) == 1
)
问题是,当我使用命令 docker-compose -f Docker-compose.dev.yml exec web python -m pytest 运行测试时(正在 web 容器的名称)我收到一个错误,因为已经有broker_id 和carrier_id 的组合。
我想要的是为每个测试恢复数据库。我怎样才能做到这一点?
编辑:
这就是我设法做我想做的事:
import os

import pytest
from starlette.testclient import TestClient
from tortoise.contrib.test import finalizer, initializer

from app.config import Settings, get_settings
from app.main import create_application


def get_settings_override():
return Settings(testing=1, database_dev_url=os.environ.get("DATABASE_TEST_URL"))


@pytest.fixture(scope="function")
def test_app():
# set up
app = create_application()
app.dependency_overrides[get_settings] = get_settings_override

with TestClient(app) as test_client:

# testing
yield test_client

# tear down


@pytest.fixture(scope="function")
def test_app_with_db():
# set up
app = create_application()
app.dependency_overrides[get_settings] = get_settings_override

# Link with DB for testing
initializer(
["app.infra.postgres.models"],
db_url=os.environ.get("DATABASE_TEST_URL"),
)

with TestClient(app) as test_client:
# testing
yield test_client

# tear down
finalizer()

最佳答案

正如 MrBean 所说,您需要为每个测试运行 fixture ,而不是为每个模块运行。
您可以像这样更改范围:

@pytest.fixture(scope="function")
def test_app_with_db():
# set up
...
或者您可以删除 scope参数,因为它默认为 function :
https://docs.pytest.org/en/stable/fixture.html#scope-sharing-fixtures-across-classes-modules-packages-or-session
这是假设您的 # teardown 中确实有一些东西 fixture 的部分。否则没有什么可以清理数据库。

关于python - 如何使用 pytest、fastapi 和 tortoise-orm 回滚每个测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63363776/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com