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

unittest测试Flask API根路径返回404错误如何解决

问题原因

路由注册逻辑写在Main类的__init__构造方法中,两种运行场景的执行逻辑差异导致了问题:

  • 直接启动main.py时,代码会进入if __name__ == "__main__"分支,执行main = Main()实例化对象,构造方法自动运行,/路径的路由才会被注册到Flask app实例上,因此直接访问服务可以得到正常响应。
  • 运行单元测试时,仅导入了Main类,直接通过类属性Main.app生成测试客户端,全程没有实例化Main对象,构造方法内的路由注册逻辑完全没有执行,Flask app中不存在/对应的路由规则,请求自然返回404状态码。

注:测试输出里Expected :404 Actual :200是unittest断言的参数顺序显示问题,不影响问题定位。

修复方案

二选一即可:

方案1:最小改动,测试时先实例化Main触发路由注册

只需要修改测试文件test_main.py的setUp方法,在生成测试客户端前先实例化Main对象,触发构造方法完成路由注册:

def setUp(self):
    # 实例化Main,执行__init__中的路由注册逻辑
    Main()
    self.ctx = Main.app.app_context()
    self.ctx.push()
    self.client = Main.app.test_client()

因为app是Main的类属性,所有实例共享同一个app对象,实例化操作就会完成路由绑定,改完再跑测试就能拿到200状态码。

方案2(推荐):调整代码结构,避免路由注册依赖类实例化

Flask不推荐把路由注册逻辑塞到类构造方法中,这种写法很容易出现漏实例化导致路由丢失的问题。更清晰的写法是把app初始化、路由注册逻辑独立出来,参考调整后的main.py:

from flask import Flask

# 独立初始化app实例
app = Flask(__name__)

# 直接注册路由,不依赖类实例化
@app.route('/', methods=['GET'])
def index():
    return "Hello - welcome to my API"

class Main:
    def __init__(self):
        # 其他业务初始化逻辑放在这里
        pass

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5003)

对应调整测试代码,直接导入独立的app实例生成测试客户端即可,不需要依赖Main类的实例化:

import unittest
# 直接导入初始化好的app实例
from src.main import app


class MainTest(unittest.TestCase):

    def setUp(self):
        self.ctx = app.app_context()
        self.ctx.push()
        self.client = app.test_client()

    def tearDown(self):
        self.ctx.pop()

    def test_index(self):
        """ Test index page of the flask API """
        response = self.client.get("/")
        self.assertEqual(response.status_code, 200)


if __name__ == "__main__":
    unittest.main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:18:17