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

Flask应用手动运行正常,pytest单元测试返回404 Not Found求助

问题根源与解决方案

你遇到的404问题核心原因很明确:测试代码使用的Flask应用实例,和你手动运行时的实例不是同一个——你把路由注册到了全局的application对象上,但测试里用create_app()创建的是一个全新的、没有任何路由的Flask实例。

具体分析你的代码问题

  1. 在web_application.py中:
    • 你创建了两个独立的Flask实例:
      • 全局的application,路由@application.route('/greetings')挂在这个实例上;
      • create_app()函数内部创建的app,这个实例没有注册任何路由,只是做了配置。
    • 另外你的代码里还缺了os模块的导入,手动运行时其实会报错,这个也要补上。
  2. 在测试代码中:
    • 你调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:26:19