python - wtforms 上的单元测试失败
问题描述
当使用 pytest 对将数据发布到烧瓶 wtforms 进行单元测试时,表单的文件数据始终为''
,这似乎数据未正确“发布”到表单,并导致form.validate_on_submit()
将始终返回False
。我WTF_CSRF_ENABLED
在测试时禁用了。
我做了一个最小的项目来演示这个问题。我没有在此处包含数据库,因为数据库在我的实际项目中运行良好。
这个最小的项目结构在这里:
.
├── app.py
├── templates
│ └── login.html
└── tests
└── test_login.py
test_login.py:
import unittest
from flask import current_app
from app import create_app
class BasicsTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app()
self.app.config['WTF_CSRF_ENABLED'] = False
self.app_context = self.app.app_context()
self.app_context.push()
self.client = self.app.test_client()
def tearDown(self):
self.app_context.pop()
def test_app_exists(self):
self.assertFalse(current_app is None)
def test_home_page(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
def test_login(self):
response = self.client.post(
'/login', data={
'username': 'a',
'password': 'a'
})
应用程序.py:
from flask import Flask, redirect, render_template, url_for, Blueprint
from flask_wtf import FlaskForm
from wtforms import PasswordField, StringField, SubmitField
from wtforms.validators import DataRequired, Length
bp = Blueprint('myapp', __name__)
@bp.route('/')
def home():
return 'hello'
@bp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(prefix='form-login-')
if form.validate_on_submit():
return redirect(url_for('home'))
return render_template('login.html', form=form)
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Log In')
def create_app():
app = Flask('__name__')
app.config['SECRET_KEY'] = 'secretkey'
app.register_blueprint(bp)
return app
解决方案
事实证明,当您的 wtforms 具有该prefix
属性时,您发布数据的方式应该会改变。
如您所见,我使用的表单是form = LoginForm(prefix='form-login-')
,而我将数据发布到表单的方式是
response = self.client.post(
'/login', data={
'username': 'a',
'password': 'a'
})
prefix
在将表单中使用的数据添加到数据字典之前,它不会正确传递数据,如下所示:
response = self.client.post(
'/login', data={
'form-login-username': 'a',
'form-login-password': 'a'
})
现在一切正常!
但是如果你想获取表单域数据,你还是应该使用form.username.data
, 没有任何prefix
.
推荐阅读
- ios - 单击后从 Cell 推送 segue 不起作用
- javascript - 使用 React 创建可重用过滤表的问题
- c# - 为不同的输入和输出设置 Mock 对象方法,警告:访问修改后的闭包
- c# - 在身份服务器上检查 JWT 的有效性
- sql - SQL获取列表中值的MAX()值
- python - 通过 Gunicorn 运行时,Flask 在模板文件夹中找不到 HTML 文件
- mysql - 带有子查询和连接的 MySQL UPDATE
- batch-file - 如何执行 .bat 以按时间顺序运行多个文件?
- javascript - 如何通过点击一个js按钮生成1到3之间的三个不同的随机数
- python - python3.7关于项目的AttributeError