使用 pytest 测试 flask_wtf/wtforms
Testing flask_wtf/wtforms with pytest
我想测试一个处理非平凡形式的 POST 路由(通过使用 flask.request.form)。我并没有真正找到一个很好的教程,因为大多数传递 json 数据而不是形式(或者是相同的?)。
我试着用下面的方式写代码:
import pytest
import app #app.app is the Flask app
@pytest.fixture
def client():
app.app.config['TESTING'] = True
with app.app.test_client() as client:
with app.app.app_context():
yield client
def test_route_webapp_post(client):
form = app.forms.ImputeForm.make_form(data_dict=app.data_dictionary.data_dict,
numeric_fields=app.binaries_dict['numeric_mappers'].keys(),
recordname2description=app.binaries_dict['recordname2description'])
rv = client.post('/web_app',form=form)
assert rv.status_code==200
表单是动态生成的,我并不总是提前知道字段是什么:
from flask_wtf import FlaskForm
from wtforms import SelectField, DecimalField, BooleanField
class ImputeForm(FlaskForm):
@classmethod
def make_form(cls, data_dict, numeric_fields, recordname2description, request_form=None):
for key in numeric_fields:
setattr(cls, key, DecimalField(id=key, label=recordname2description[key].split('(')[0]))
setattr(cls, 'mask_' + key, BooleanField(label='mask_' + key))
for key in data_dict:
setattr(cls, key, SelectField(id=key, label=recordname2description[key],
choices=[(-1, 'None selected')]+list(data_dict[key].items())))
setattr(cls, 'mask_' + key, BooleanField(label='mask_' + key))
instance = cls(request_form)
return instance
但这并没有真正起作用,因为我无法在测试用例中创建一个表单并获取
E RuntimeError: Working outside of request context.
E
E This typically means that you attempted to use functionality that needed
E an active HTTP request. Consult the documentation on testing for
E information about how to avoid this problem.
那么测试我的表单的正确方法是什么(特别是我可以发送一个空的表单)?
正确的方法是创建 python 字典并将其作为 "data" 传递,而不是尝试创建表单。
在特定情况下,这涉及创建一个新函数:
def make_from_data( data_dict, numeric_fields):
data = dict()
for key in numeric_fields:
data[key]='234'
data['mask_' + key]='y'
for key in data_dict:
data[key]=-1
data['mask_' + key]='y'
return data
并按如下方式传递:
def test_route_webapp_post(client):
data = make_from_data(data_dict=app.data_dictionary.data_dict,
numeric_fields=app.binaries_dict['numeric_mappers'].keys())
rv = client.post('/web_app',data=data)
assert rv.status_code==200
我想测试一个处理非平凡形式的 POST 路由(通过使用 flask.request.form)。我并没有真正找到一个很好的教程,因为大多数传递 json 数据而不是形式(或者是相同的?)。
我试着用下面的方式写代码:
import pytest
import app #app.app is the Flask app
@pytest.fixture
def client():
app.app.config['TESTING'] = True
with app.app.test_client() as client:
with app.app.app_context():
yield client
def test_route_webapp_post(client):
form = app.forms.ImputeForm.make_form(data_dict=app.data_dictionary.data_dict,
numeric_fields=app.binaries_dict['numeric_mappers'].keys(),
recordname2description=app.binaries_dict['recordname2description'])
rv = client.post('/web_app',form=form)
assert rv.status_code==200
表单是动态生成的,我并不总是提前知道字段是什么:
from flask_wtf import FlaskForm
from wtforms import SelectField, DecimalField, BooleanField
class ImputeForm(FlaskForm):
@classmethod
def make_form(cls, data_dict, numeric_fields, recordname2description, request_form=None):
for key in numeric_fields:
setattr(cls, key, DecimalField(id=key, label=recordname2description[key].split('(')[0]))
setattr(cls, 'mask_' + key, BooleanField(label='mask_' + key))
for key in data_dict:
setattr(cls, key, SelectField(id=key, label=recordname2description[key],
choices=[(-1, 'None selected')]+list(data_dict[key].items())))
setattr(cls, 'mask_' + key, BooleanField(label='mask_' + key))
instance = cls(request_form)
return instance
但这并没有真正起作用,因为我无法在测试用例中创建一个表单并获取
E RuntimeError: Working outside of request context.
E
E This typically means that you attempted to use functionality that needed
E an active HTTP request. Consult the documentation on testing for
E information about how to avoid this problem.
那么测试我的表单的正确方法是什么(特别是我可以发送一个空的表单)?
正确的方法是创建 python 字典并将其作为 "data" 传递,而不是尝试创建表单。
在特定情况下,这涉及创建一个新函数:
def make_from_data( data_dict, numeric_fields):
data = dict()
for key in numeric_fields:
data[key]='234'
data['mask_' + key]='y'
for key in data_dict:
data[key]=-1
data['mask_' + key]='y'
return data
并按如下方式传递:
def test_route_webapp_post(client):
data = make_from_data(data_dict=app.data_dictionary.data_dict,
numeric_fields=app.binaries_dict['numeric_mappers'].keys())
rv = client.post('/web_app',data=data)
assert rv.status_code==200