See*_*Bee 8 html python forms unit-testing flask
我想在我的烧瓶应用程序中添加单元测试,以测试有效和无效登录+注册时的表单行为.目前,我在一个页面和路由上托管了注册表单和登录表单,并使用隐藏的输入字段来标识提交的两个表单中的哪一个/确定下一个操作.
我的问题是 - 如何编写针对页面上特定表单的单元测试?到目前为止,我看到的所有示例都将数据发布到特定路径,这正是我正在做的事情.但这是失败的,因为我需要一种额外的方式来说"我们正在提交x形式".
那么有没有办法在帖子请求中添加"我们正在提交x表单"?
**编辑添加,以下是我试图在后期数据字典中传递隐藏表单数据的不同方法,但没有成功.
data = dict(username="test@gmail.com", password="test", login_form)
data = dict(username="test@gmail.com", password="test", "login_form")
data = dict(username="test@gmail.com", password="test", login_form=True)
Run Code Online (Sandbox Code Playgroud)
登录单元测试:
from app import app
import unittest
class FlaskTestCase(unittest.TestCase):
#ensure that login works with correct credentials
def test_correct_login(self):
tester = app.test_client(self)
response = tester.post(
'/login',
data = dict(username="test@gmail.com", password="test"),
follow_redirects=True
)
self.assertIn(b'you are logged in', response.data)
Run Code Online (Sandbox Code Playgroud)
views.py中的登录路由:
@app.route('/login', methods=['POST', 'GET'])
def login():
login_form = LoginForm()
signup_form = SignupForm()
error_login = ''
error_signup = ''
#login form
if 'login_form' in request.form and login_form.validate():
# do login form stuff
#signup form
if 'signup_form' in request.form and signup_form.validate():
# do signup form stuff
return render_template('login.html', login_form=login_form, signup_form=signup_form, error=error)
Run Code Online (Sandbox Code Playgroud)
的login.html:
<div class="login-form form-400">
<h3>Log In To Your Account</h3>
<form action="" method="post">
<input type="hidden" name="login_form">
{% if error_login != '' %}
<label class="error">
{{ error_login }}
</label>
{% endif %}
{% from "_formhelper.html" import render_field %}
{{ login_form.hidden_tag() }}
{{ render_field(login_form.email, placeholder="Your Email", class="form-item__full", type="email") }}
{{ render_field(login_form.password, placeholder="Your Password", class="form-item__full") }}
<input type="submit" value="Login" class="button button-blue">
</form>
</div>
<p class="login-divider">or</p>
<div class="signup-form form-400">
<h3>Create a New Account</h3>
<form action="" method="post">
<input type="hidden" name="signup_form">
{% if error_signup != '' %}
<label class="error">
{{ error_signup | safe}}
</label>
{% endif %}
{% from "_formhelper.html" import render_field %}
{{ signup_form.hidden_tag() }}
{{ render_field(signup_form.username, placeholder="Pick a Username", class="form-item__full") }}
{{ render_field(signup_form.email, placeholder="Your Email", class="form-item__full", type="email") }}
{{ render_field(signup_form.password, placeholder="Create a Password", class="form-item__full") }}
<input type="submit" value="Sign Up" class="button button-green">
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
好吧,我想通了。要传递登录表单信息,我必须最终在登录表单上传递一个空字符串,如下所示:
def test_correct_login(self):
tester = app.test_client(self)
response = tester.post(
'/login',
data = dict(username="test@gmail.com", password="test", login_form=""),
follow_redirects=True
)
self.assertIn(b'you are logged in', response.data)
Run Code Online (Sandbox Code Playgroud)
我通过print request.form
在该路线的views.py中添加一个来做到这一点,然后看到空字符串。
它仍然失败,但因为login_form.validate()
WTForms 模块添加的 csrf 令牌而失败。最终,这次讨论有了答案。
Flask-WTF / WTForms 与 Unittest 验证失败,但无需 Unittest 即可工作
感谢@drdrez 的建议!
更新:感谢您用您已经尝试过的内容更新您的问题!关于导致该问题的原因,我还有一些其他想法。
让我们继续查看 HTML 并尝试了解您的程序所基于的技术。在服务器端的 login.html 文件中,请注意以下几行:
{% from "_formhelper.html" import render_field %}
{{ login_form.hidden_tag() }}
{{ render_field(login_form.email, placeholder="Your Email", class="form-item__full", type="email") }}
{{ render_field(login_form.password, placeholder="Your Password", class="form-item__full") }}
Run Code Online (Sandbox Code Playgroud)
它不是 HTML,并且可能在服务器端进行处理以生成 HTML 并提供给客户端。包含的行login_form.hidden_tag()
看起来很有趣,因此我建议在浏览器中加载此页面并检查提供给客户端的 HTML。不幸的是,我之前没有使用过Flask,所以我无法提供任何更直接的帮助。
不过,我的建议是继续深入研究 Flask 和 HTML 表单的工作原理。Python 的好处是您可以访问库的源代码,这使您可以了解它们的工作原理,以便您可以学习如何使用它们并修复使用它们的应用程序中的错误。
抱歉无法给您更直接的帮助,祝您好运!
让我们看一下login.html。当你提交表单时,views.py 中的登录路由如何知道提交的是哪个表单?如果您了解 HTML 表单,则<input>
在本例中,嵌套在表单中的元素用于将数据发布到您的服务器/应用程序。
回到login.html,注意这两行:
...
<h3>Log In To Your Account</h3>
<input type="hidden" name="login_form">
...
<h3>Create a New Account</h3>
<form action="" method="post">
<input type="hidden" name="signup_form">
...
Run Code Online (Sandbox Code Playgroud)
这些<input>
元素的类型为“隐藏”,因此它们不会显示,名称为“login_form”和“signup_form”,包含在表单提交的数据中。
现在在views.py的登录路径中,您会注意到有两行:
#login form
if 'login_form' in request.form and login_form.validate():
# do login form stuff
#signup form
if 'signup_form' in request.form and signup_form.validate():
# do signup form stuff
Run Code Online (Sandbox Code Playgroud)
这些正在测试列表中是否存在短语“login_form”或“signup_form” request.form
。现在回到你的单元测试:
response = tester.post(
'/login',
data = dict(username="test@gmail.com", password="test"),
follow_redirects=True
)
Run Code Online (Sandbox Code Playgroud)
请注意您在 中传递的数据dict
,这是模仿表单数据,因此您可能应该包含“login_form”或“signup_form”以正确模仿 HTML 表单的行为。
如果您不熟悉 HTML 表单和 HTTP Post,我建议您搜索一些教程,或者只是阅读MDN或其他地方的文档。当基于某种技术(如 HTTP 和 HTML)构建软件时,当您在自己的软件中遇到错误时,了解这些技术的工作原理会很有帮助。
希望这有帮助,如果我可以澄清任何事情,请告诉我!
归档时间: |
|
查看次数: |
2777 次 |
最近记录: |