You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用pytest测试FastAPI应用,避免测试间共享应用状态

解决FastAPI+pytest测试中全局状态污染的问题

你的问题核心是测试会话中共享了同一个全局状态,导致测试用例互相干扰。以下是几种可行的解决方案:

方法1:测试前自动重置全局状态

利用pytest的autouse fixture,在每个测试执行前重置目标模块的全局变量。

创建conftest.py文件(pytest会自动加载该文件):

import pytest
import main

@pytest.fixture(autouse=True)
def reset_global_state():
    # 测试前重置初始状态
    main.my_state = False
    yield
    # 测试结束后再次重置(可选,确保后续测试不受影响)
    main.my_state = False

修改后,所有测试用例执行前都会自动把my_state恢复为初始的False,测试间不会互相干扰。

方法2:用工厂函数创建独立App实例

将App的创建逻辑封装成工厂函数,每次测试生成全新的App实例,彻底隔离状态。

修改main.py:

from fastapi import FastAPI

def create_app():
    app = FastAPI()
    # 将状态存储在app的state属性中,而非全局变量
    app.state.my_state = False

    @app.get("/my_state/")
    def return_my_state():
        return {"state": app.state.my_state }

    @app.post("/my_state/")
    def set_my_state(content: dict):
        app.state.my_state = content['set']
    
    return app

# 保留全局app实例,方便正常启动服务
app = create_app()

在conftest.py中定义测试用的client fixture:

import pytest
from fastapi.testclient import TestClient
from main import create_app

@pytest.fixture
def client():
    # 每个测试都生成全新的App和Client
    app = create_app()
    return TestClient(app)

修改测试文件(以test_file1.py为例):

import pytest

@pytest.mark.asyncio
async def test_check_status(client):
    client.post("/my_state/", json={"set": True})
    assert client.get("/my_state/").json()['state'] is True

test_file2.py同理,每个测试用例都会拿到独立的App实例,状态完全隔离。

方法3:用依赖注入管理状态

将状态封装为依赖类,测试时通过覆盖依赖来重置状态,更符合FastAPI的设计规范。

修改main.py:

from fastapi import FastAPI, Depends

class AppState:
    def __init__(self):
        self.my_state = False

def get_app_state():
    return AppState()

app = FastAPI()

@app.get("/my_state/")
def return_my_state(state: AppState = Depends(get_app_state)):
    return {"state": state.my_state }

@app.post("/my_state/")
def set_my_state(content: dict, state: AppState = Depends(get_app_state)):
    state.my_state = content['set']

在conftest.py中定义带依赖覆盖的client fixture:

import pytest
from fastapi.testclient import TestClient
from main import app, AppState, get_app_state

@pytest.fixture
def client():
    # 每次测试创建全新的状态实例
    def override_get_state():
        return AppState()
    
    app.dependency_overrides[get_app_state] = override_get_state
    client = TestClient(app)
    yield client
    # 测试结束后清除依赖覆盖,避免影响其他测试
    app.dependency_overrides.clear()

测试文件的写法与方法2一致,每个测试都会使用独立的状态实例。

内容的提问来源于stack exchange,提问作者ntriisii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:32:47