【问题标题】:Correct testing with request context in Flask在 Flask 中使用请求上下文进行正确测试
【发布时间】:2015-12-14 21:37:29
【问题描述】:

我正在尝试通过显式调用路由函数来执行一些测试。

from flask import Flask
app = Flask(__name__)


@app.route("/")
def index():
    myfunc()
    return "Index!"

@app.route("/a")
def hello():
    return "hello"

def myfunc():
    with app.test_request_context('/', method='POST'):
        app.hello()


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

但它失败了:

Traceback (most recent call last):
  File "python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "test.py", line 9, in index
    myfunc()
  File "test.py", line 18, in myfunc
    app.hello()
AttributeError: 'Flask' object has no attribute 'hello'

这样可以测试路由功能吗?

是的例子有点难看,但我需要弄清楚它有什么问题。

【问题讨论】:

    标签: python python-2.7 flask


    【解决方案1】:

    要执行“内部重定向”,或从另一个视图调用视图,您需要使用正确的 url 和任何其他所需数据推送一个新的请求上下文,然后让 Flask 调度请求。您可以从内部视图返回值,也可以在外部视图中返回您自己的响应。

    from flask import Flask, request, url_for
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        with app.test_request_context(
                url_for('hello'),
                headers=request.headers.to_list(),
                query_string=request.query_string
        ):
            return app.dispatch_request()
    
    @app.route('/greet')
    def hello():
        return 'Hello, {}!'.format(request.args.get('name', 'World'))
    
    app.run()
    

    导航到http://127.0.0.1/?name=davidism 会返回Hello, davidism!,这是来自hello 视图的响应。


    您不会通过像这样从正在运行的应用程序调用视图来测试视图。要测试 Flask 应用程序,您将使用单元测试和测试客户端 as described in the docs

    with app.test_client() as c:
        r = c.get('/a')
        assert r.data.decode() == 'hello'
    

    【讨论】:

      【解决方案2】:

      hello 是一个常规函数,用 app.route 装饰它不会将它添加到 app 对象中。你是不是只想调用 hello 函数,像这样:

      with ...:
          hello()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-10
        • 2013-06-10
        • 2020-11-16
        • 1970-01-01
        • 1970-01-01
        • 2013-06-26
        • 2014-07-22
        • 1970-01-01
        相关资源
        最近更新 更多