繁体   English   中英

测试使用 Flask-WTF validate_on_submit 的 POST

[英]Testing a POST that uses Flask-WTF validate_on_submit

我很难测试一个 POST 以将一个类别添加到我使用 Flask_WTF 进行验证和 CSRF 保护的数据库中。 对于 CRUD 操作,pm 我的网站。 我用过 Flask、Flask_WTF 和 Flask-SQLAlchemy。 这是我的第一个独立项目,我发现自己对如何测试 Flask-WTForm validate_on_submit function 有点迷茫。

这是模型:

class Users(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(250), unique=True)

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True, unique=True)
    name = db.Column(db.String(250), nullable=False, unique=True)
    users_id = db.Column(db.Integer, db.ForeignKey('users.id'))

这是表格:

class CategoryForm(Form):
    name = StringField(
        'Name', [validators.Length(min=4, max=250, message="name problem")])

这是 controller:

@category.route('/category/add', methods=['GET', 'POST'])
@login_required
def addCategory():
    """ Add a new category.
        Returns: Redirect Home.
    """
    # Initiate the form.
    form = CategoryForm()
    # On POST of a valid form, add the new category.
    if form.validate_on_submit():
        category = Category(
            form.name.data, login_session['users_id'])
        db.session.add(category)
        db.session.commit()
        flash('New Category %s Successfully Created' % category.name)
        return redirect(url_for('category.showHome'))
    else:
        # Render the form to add the category.
        return render_template('newCategory.html', form=form)

如何使用 validate_on_submit function 为 if 语句编写测试?

使用pytest和pytest和SQLAlchemyDelightful测试推荐的conftest.py ,这是一个确认添加类别的测试。

def test_add_category_post(app, session):
    """Does add category post a new category?"""
    TESTEMAIL = "test@test.org"
    TESTUSER = "Joe Test"
    user = Users.query.filter(Users.email==TESTEMAIL).first()
    category = Category(name="Added Category", users_id=user.id)
    form = CategoryForm(formdata=None, obj=category)
    with app.test_client() as c:
        with c.session_transaction() as sess:
            sess['email'] = TESTEMAIL
            sess['username'] = TESTUSER 
            sess['users_id'] = user.id
            response = c.post(
                '/category/add', data=form.data, follow_redirects=True)
    assert response.status_code == 200
    added_category = Category.query.filter(
        Category.name=="Added Category").first()
    assert added_category
    session.delete(added_category)
    session.commit()

请注意,新类别已分配给变量,然后用于创建表单。 表格的数据用于帖子中。

您的应用程序应该有不同的配置,具体取决于您是本地/生产/执行单元测试。 您可以设置一种配置

WTF_CSRF_ENABLED = False

请参阅flask-wtforms文档

根据@mas 的评论,我得到了这个对我有用的解决方案:

topic_name = "test_topic"
response = fixt_client_logged_in.post('/create', data={"value":topic_name}, follow_redirects=True)

我正在使用此表格 class:

class SimpleSubmitForm(FlaskForm):
    value = StringField(validators=[DataRequired()])
    submit = SubmitField()

在这个 html 文件中:

{{form.hidden_tag()}}

{{form.value.label("Topic", class="form-label")}}
{{form.value(value=topic_name, class="form-control")}}
<br/>
{{form.submit(value="submit", class="btn btn-primary")}}

请注意,我将 hidden_tag 用于 CSRF 安全性,但是在测试时,我有一条额外的行可以将其停用:

app.config['WTF_CSRF_ENABLED']=False

我不知道它实际上是如何工作的,但我的假设是:wtform FlaskForm object 查看请求的“数据”属性,它应该是一个字典。 然后它在该字典中查找与其属性同名的键。 如果它找到一个具有相同名称的键,那么它会将那个值分配给它的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM