为Flask测试客户端生成URL
问题描述:
我正在尝试使用pytest为Flask应用程序编写单元测试。我有一个应用程序的工厂:为Flask测试客户端生成URL
def create_app():
from flask import Flask
app = Flask(__name__)
app.config.from_object('config')
import os
app.secret_key = os.urandom(24)
from models import db
db.init_app(app)
return app
和测试类:
class TestViews(object):
@classmethod
def setup_class(cls):
cls.app = create_app()
cls.app.testing = True
cls.client = cls.app.test_client()
@classmethod
def teardown_class(cls):
cls.app_context.pop()
def test_create_user(self):
"""
Tests the creation of a new user.
"""
view = TestViews.client.get(url_for('create_users')).status_code == 200
但是当我运行我的测试中,我得到以下错误:
RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.
谷歌搜索这告诉我(我认为)使用测试客户端应创建一个自动应用程序上下文。我错过了什么?
答
使用测试客户端发出请求确实会推送应用程序上下文(间接)。但是,您将url_for
在测试请求调用中可视化的内容与它实际上在内部调用的想法相混淆。首先对url_for
调用进行评估,结果传递给client.get
。
url_for
通常是用于内该应用生成的URL ,单元测试是外部。通常,您只需在请求中准确写入您要测试的URL,而不是生成它。
self.client.get('/users/create')
如果您真的想在这里使用url_for
,您必须在应用程序上下文中执行此操作。请注意,如果您处于应用上下文中,但不是请求上下文,则必须设置SERVER_NAME
配置并通过_external=False
。但是,再次,你应该写出你想要测试的URL。
app.config['SERVER_NAME'] = 'localhost'
with self.app.app_context():
url = url_for(..., _external=False)
self.client.get(url, ...)