【问题标题】:Prevent Pytest from reusing app object between different test files防止 Pytest 在不同的测试文件之间重用 app 对象
【发布时间】:2021-01-28 02:02:41
【问题描述】:

我有一个包含多个路由文件的项目,每个文件都有一个APIRouter。我在main.py 中包含所有路由器,如下所示:

from init import app
import customer
import receipt

app.include_router(customer.router, prefix='/api/customer', tags=["Customer"])
app.include_router(receipt.router, prefix='/api/receipt', tags=["Receipt"])

init.py:

from fastapi import FastAPI
app = FastAPI()

customer.py 我有这个(简化的)代码:

from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()

class CustomerModel(BaseModel):
    name: str

@router.post('/')
def register_new_customer(data: CustomerModel):
    pass

在我的receipt.py 我有类似的代码:

from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()

class ReceiptModel(BaseModel):
    price: float

@router.post('/')
def add_new_receipt(data: ReceiptModel):
    pass

我也对这两个文件进行了单元测试。 test_receipt.py:

from receipt import router
from init import app

app.include_router(router)
client = TestClient(app)

class TestReceiptsRoutes:
    def test_can_create_new_receipt(self):
        response = client.post('/', json={'price': 10.0})
        assert response.status_code == 200

test_customer.py 类似

如果我单独运行每个文件,例如pytest test_receipt.pypytest test_customer.py 工作正常,但是当我一起运行它们时,我的 test_receipt.py 失败,说 response.status_code422。发生的情况是我的 app/ 路径上添加了两个 POST 路由,因此当接收运行测试时,它实际上是在调用客户路由并且验证失败。

问题:如何确保app 不会在测试文件之间重复使用?

我知道我可以将 app.include_router 行从 main 复制/粘贴到测试中(带有完整路径),这就是我目前正在做的解决方法,我只是想知道是否有办法确保应用程序在每个测试套件中都是独立的。

【问题讨论】:

  • 也许您可以重新加载 init 模块,例如from importlib import reload 然后reload(init) 然后重新导入from init import app。如果您使用的是unittest.TestCase,您可以将其添加到您的setUp 方法中,或者如果您使用的是现代的pytest,则可以将其添加到您的夹具中,参见例如docs.pytest.org/en/stable/fixture.html

标签: python unit-testing pytest fastapi


【解决方案1】:

假设app 对象是有状态的,重新加载init 模块然后重新导入app 可能会有所帮助。

以下是使用夹具的方法:

import pytest
from importlib import reload

import init


@pytest.fixture
def app():
    app = reload(init).app
    app.include_router(foo.router, ...)
    return app


def test_foo(app):
    client = TestClient(app)
    ...
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2018-02-12
    • 2019-01-02
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多