Flask测试报错TypeError:缺少environ和start_response参数
Flask测试报错:TypeError: Flask.call()缺少2个必要位置参数
我写了个简单的Flask应用,开发模式下运行正常,但写测试时碰到这个错误:
TypeError: Flask.call() missing 2 required positional arguments: 'environ' and 'start_response'
测试代码及错误详情:
@pytest.fixture() def app(): > app = main.app() E TypeError: Flask.__call__() missing 2 required positional arguments: 'environ' and 'start_response' test_app.py:22: TypeError
应用代码(main.py):
from flask import Flask, render_template, request, redirect, url_for from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # /// = 相对路径,//// = 绝对路径 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) """模型和路由定义"""
文件夹结构:主目录下包含main.py、test_app.py,以及相关数据库文件等。
我猜可能是Werkzeug的问题,但不知道怎么在标准Flask实例化里处理。
参考示例代码:
from werkzeug.wrappers import Request, Response def application(environ, start_response): request = Request(environ) text = 'Hello %s!' % request.args.get('name', 'World') response = Response(text, mimetype='text/plain') return response(environ, start_response)
解决方法
问题出在测试代码里的main.app()调用——你在main.py里已经直接实例化了Flask对象app,它不是一个可调用的创建函数,直接加括号调用会触发Flask的WSGI接口方法__call__,而这个方法确实需要environ和start_response两个参数,所以报错。
方案1:直接引用已实例化的app对象
修改测试fixture,去掉括号:
@pytest.fixture() def app(): return main.app
方案2:改用Flask应用工厂模式(推荐)
更规范的做法是把app的创建封装成函数,方便测试和扩展:
在main.py里修改:
from flask import Flask, render_template, request, redirect, url_for from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() def create_app(): app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) # 在这里定义模型和路由 return app # 开发模式下运行用 if __name__ == "__main__": app = create_app() app.run()
然后测试fixture里调用这个函数:
@pytest.fixture() def app(): app = main.create_app() # 可添加测试专属配置,比如用内存数据库 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' return app
这样做不仅解决了测试报错的问题,还让应用结构更清晰,方便后续扩展和多环境配置。
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

