Sanic从21.x升级至22.12后app.test_client测试全部失效求助
Sanic 22.12升级后app.test_client测试失效的解决办法
升级Sanic到22.12版本后,原有基于app.test_client的测试会报错找不到应用实例,核心原因是Sanic 22.x调整了多进程模式下的应用注册机制,子进程无法读取主进程的应用注册表。以下是几种可行的解决方法:
方法一:测试时强制启用单进程模式
直接在测试请求中指定single_process=True,让测试客户端以单进程运行:
from server import app def test_deploy_plan(): _, response = app.test_client.get('/some/route', single_process=True) assert response.status_code == 200
如果有多个测试用例,可用pytest自动fixture全局设置:
import pytest from server import app @pytest.fixture(autouse=True) def enable_single_process(): app.config.SINGLE_PROCESS = True yield def test_deploy_plan(): _, response = app.test_client.get('/some/route') assert response.status_code == 200
方法二:用AppLoader重构应用加载逻辑
按照Sanic官方推荐的AppLoader模式重构server.py,确保应用实例在任何环境下都能被正确加载:
from sanic import Sanic from sanic.testing import TestManager from sanic.loader import AppLoader def create_app(): app = Sanic("app_name") app.config.RESPONSE_TIMEOUT = 3600 TestManager(app) # 保留原有的路由定义 # ... return app if __name__ == "__main__": loader = AppLoader(factory=create_app) app = loader.load() app.run(host="0.0.0.0", port=8000)
修改测试代码,通过工厂函数创建应用实例:
from server import create_app def test_deploy_plan(): app = create_app() _, response = app.test_client.get('/some/route') assert response.status_code == 200
也可用pytest fixture复用应用实例,提升测试效率:
import pytest from server import create_app @pytest.fixture def app(): return create_app() def test_deploy_plan(app): _, response = app.test_client.get('/some/route') assert response.status_code == 200
问题根源说明
Sanic 21.x版本默认单进程运行,应用实例直接注册到全局注册表中,测试时可正常读取。而22.x版本默认启用多进程生产模式,当从外部模块导入app实例时,测试启动的子进程无法访问主进程的注册表,因此抛出"app_name not found"的错误。上述两种方法分别从测试运行模式和应用加载机制入手,解决了实例查找的问题。
内容的提问来源于stack exchange,提问作者rbm
相关产品推荐
相关产品推荐

