今天写单元测试发现了一个常见的问题,即测试时发送POST请求时如何传入布尔值数据(勾选框字段值)?答案是:你没法直接传递布尔值。其实这个答案相当显而易见,客户端当然没法向服务器端发送Python类型的数据,数据的转换是在接受到请求数据后在服务器端进行的。之前在不借助Flask-WTF/WTForms,手动编写表单并处理时就已经注意到了这个问题,不过在测试中不太容易想到。
首先,我们需要了解一下勾选框(<input type="checkbox">
)提交的行为:
- 如果没有勾选,那么勾选框字段的值为空值,而且这个字段不会被序列化到请求中;在服务器端,WTForms会将其转换为
False
。 - 如果勾选框被勾选,那么传入服务器端的数据会是该字段value属性的值,如果value属性的值为空,那么则提交字符串
"on"
;在服务器端,WTForms会将其转换为True
。
也就是说,勾选框的数据只要不为空,WTForms就会将其转换为True。所以,在测试中,如果你想让勾选框的值最终转换为True,那么就传入任意字符串;反之则传递空字符串或直接不加入该字段。下面是传入空字符串的示例:
def test_privacy_setting(self): self.login() response = self.client.post(url_for('user.privacy_setting'), data=dict( public_collections='', # <-- ), follow_redirects=True) user = User.query.get(1) self.assertEqual(user.public_collections, False)
顺便说一句,基于勾选框的提交行为,如果没有使用Flask-WTF/WTForms,那么在手动处理提交数据的时候也要进行相应的处理:没有在request.form
中获取到勾选框字段(比如,request.form.get('remember')
会是None
),即表示没有勾选,那么就转换为False;勾选框字段一旦出现,那么就表示勾选,转换为True
。