问题
I'm writing several different flask forms. So far, what I've done to test the routes that I use with those forms is.
- Creating the form object
- Populating the form
- Posting the form data
For example, this works (short version of the class):
class RequestForm(FlaskForm):
project = SelectField(label='Project', id='project', coerce=str)
name = StringField('Environment Name', id='env_name', validators=[DataRequired()])
requested_by = StringField('Requested By', validators=[DataRequired()])
tag = StringField('Tag')
required_from = DateField('Required From', format='%Y-%m-%d', validators=[DataRequired()])
required_to = DateField('Required To', format='%Y-%m-%d', validators=[Optional()])
And when testing:
def test_post_full_request_is_correct(self):
with self.app.test_client() as http_client:
self.login(http_client)
required_from = str(datetime.datetime.today().date() + datetime.timedelta(days=1))
form = RequestForm()
form.project.data = 'SO'
form.name.data = 'TEST02'
form.requested_by.data = 'dev01'
form.required_from.data = required_from
form.env_type.data = 'DEV'
form.location.data = 'Narnia'
form.size.data = 'L'
form.resilience.data = '0'
form.submit.data = True
response = http_client.post('/request', data=form.data)
This works fine.
However, I've also got these forms. The main one being RequestsComponentsForm
.
class RequestComponentForm(FlaskForm):
component = StringField('Name', validators=[DataRequired()])
source = SelectField('Source', choices=[('nexus', 'Nexus')])
version = StringField('Version')
def __init__(self, *args, **kwargs):
kwargs['csrf_enabled'] = False
super(RequestComponentForm, self).__init__(*args, **kwargs)
class RequestComponentsForm(FlaskForm):
components = FieldList(FormField(RequestComponentForm))
submit = SubmitField('Request Environment')
It works like a charm when testing it manually. However, when I tried automated testing:
c_form = RequestComponentsForm()
components = ['app-a', 'app-b', 'app-c', 'app-d', 'app-e', 'app-f']
test_versions = ['1.2.3', '3.2.1', '2.1.3', '5.7.1', '3.6.3', '1.4.6']
for c, v in zip(log_design_components, test_versions):
entry = RequestComponentForm()
entry.component = c
entry.source = 'nexus'
entry.version = v
c_form.components.append_entry(entry)
response = http_client.post('/request{0}components'.format(env_request_id),
headers={'Referer': good_referrer},
data=c_form.data)
I get the following:
venv/lib/python3.6/site-packages/werkzeug/test.py:349: DeprecationWarning: it's no longer possible to pass dicts as `data`. Use tuples or FileStorage objects instead.
I don't understand why my approach to testing the first form works and the same approach for the 2nd one doesn't.
Any help would be greatly appreciated.
Thanks!
Update
This is what the first form's data looks like:
{
'project': 'SO',
'name': 'TEST02',
'requested_by': 'dev01',
'tag': '',
'required_from': '2018-07-11',
'required_to': None,
'monday_on': None,
'monday_off': None,
'tuesday_on': None,
'tuesday_off': None,
'wednesday_on': None,
'wednesday_off': None,
'thursday_on': None,
'thursday_off': None,
'friday_on': None,
'friday_off': None,
'saturday_on': None,
'saturday_off': None,
'sunday_on': None,
'sunday_off': None,
'env_type': 'DEV',
'location': 'Narnia',
'size': 'L',
'resilience': '0',
'submit': True
}
And the second:
{
'components': [
{
'component': 'app-a',
'source': 'nexus',
'version': '1.2.3'
},
{
'component': 'app-b',
'source': 'nexus',
'version': '3.2.1'
},
{
'component': 'app-c',
'source': 'nexus',
'version': '2.1.3'
},
{
'component': 'app-d',
'source': 'nexus',
'version': '5.7.1'
},
{
'component': 'app-e',
'source': 'nexus',
'version': '3.6.3'
},
{
'component': 'app-f',
'source': 'nexus',
'version': '1.4.6'
}
],
'submit': True
}
They're both dictionaries, so I really don't understand why the first one would work and the other one won't.
回答1:
FieldList is a handy wrapper of a group of fields in WTF. While posting data, you should use the original form, for the second form, the payload should be as follows:
{
'components-0-component': 'app-a',
'components-0-source': 'nexus',
'components-0-version': '1.2.3',
'components-1-component': 'app-b',
'components-1-source': 'nexus',
'components-1-version': '3.2.1',
...
}
来源:https://stackoverflow.com/questions/51263328/cant-post-flask-form-data-for-testing-fieldlist-deprecationwarning