Flask应用手动运行正常,pytest单元测试返回404 Not Found求助
问题根源与解决方案
你遇到的404问题核心原因很明确:测试代码使用的Flask应用实例,和你手动运行时的实例不是同一个——你把路由注册到了全局的application对象上,但测试里用create_app()创建的是一个全新的、没有任何路由的Flask实例。
具体分析你的代码问题
- 在
web_application.py中:- 你创建了两个独立的Flask实例:
- 全局的
application,路由@application.route('/greetings')挂在这个实例上; create_app()函数内部创建的app,这个实例没有注册任何路由,只是做了配置。
- 全局的
- 另外你的代码里还缺了
os模块的导入,手动运行时其实会报错,这个也要补上。
- 你创建了两个独立的Flask实例:
- 在测试代码中:
- 你调用
create_app()获取的是那个空的Flask实例,自然找不到/greetings路由,返回404。
- 你调用
修正步骤
第一步:修复Flask应用结构(统一实例与路由)
修改web_application.py,把路由注册到工厂函数创建的实例上,同时保留全局实例用于手动运行:
from flask import Flask, request, jsonify, send_from_directory import os # 补上缺失的os导入 from python.Greeting import Greeting def create_app(test_config=None): # create and configure the app app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( SECRET_KEY='mega_developer', DATABASE=os.path.join(app.instance_path, 'web_application.sqlite'), ) try: os.makedirs(app.instance_path) except OSError: pass # 把路由注册到工厂创建的app实例上 @app.route('/greetings', methods=['GET', 'POST']) def hello(): return jsonify(hello = request.args.get('name', 'world', str)) return app # 全局实例,用于手动运行(比如flask run) application = create_app()
第二步:优化测试代码(符合pytest最佳实践)
修改test_web_application.py,用fixture直接返回测试客户端,避免手动管理实例:
import tempfile import pytest import web_application @pytest.fixture def client(): # 创建测试用的Flask实例 app = web_application.create_app() app.config['TESTING'] = True app.config['DEBUG'] = False app.config['WTF_CSRF_ENABLED'] = False app.config['DATABASE'] = tempfile.mkstemp() # 生成测试客户端并传递给测试用例 with app.test_client() as client: yield client def test_hello_get(client): response = client.get('/greetings?name=Rick Sanchez') # 断言状态码 assert response.status_code == 200 # 额外断言返回内容是否正确 assert response.json == {'hello': 'Rick Sanchez'}
为什么这样修改能解决问题?
现在无论是手动运行(用全局的application,它是create_app()的返回值),还是测试(用create_app()创建的实例),使用的都是同一个带有/greetings路由的Flask实例结构,自然能正确匹配路由,返回200状态码。
内容的提问来源于stack exchange,提问作者Thomas Fritz
相关产品推荐
相关产品推荐

