admin管理员组文章数量:1277298
I have a flask app based on the tutorial here /. The tutorial comes with a test suite but having adapted the app to use WTForms the tests that post form data stopped working. I can see that's because none of the forms validate as they don't include a CSRF token. How can I add the token to the post data being sent? I came across this rather old gist showing how to do it but it appears to be out of date for the version of Werkzeug I'm using, as it refers to self.cookie_jar
which has been removed -- .
I'm using Flask==3.1.0 flask_wtf==1.2.2 pytest==8.3.4 selenium==4.29.0 Werkzeug==3.1.3 WTForms==3.2.1
tests/conftest.py
import os
import tempfile
import pytest
from flaskr import create_app
from flaskr.db import get_db, init_db
with open(os.path.join(os.path.dirname(__file__), 'data.sql'), 'rb') as f:
_data_sql = f.read().decode('utf8')
@pytest.fixture
def app():
db_fd, db_path = tempfile.mkstemp()
app = create_app({
'TESTING': True,
'DATABASE': db_path,
})
with app.app_context():
init_db()
get_db().executescript(_data_sql)
yield app
os.close(db_fd)
os.unlink(db_path)
@pytest.fixture
def client(app):
return app.test_client()
@pytest.fixture
def runner(app):
return app.test_cli_runner()
tests/test_auth.py
import pytest
from flask import g, session
from flaskr.db import get_db
def test_register(client, app):
assert client.get('/auth/register').status_code == 200
response = client.post_csrf(
'/auth/register', data={'username': 'a', 'password': 'a'}
, follow_redirects=True)
print(f'{response.status=}')
print(f'{response.response=}')
for x in response.response:
print(x)
assert response.headers["Location"] == "/auth/login"
with app.app_context():
assert get_db().execute(
"SELECT * FROM user WHERE username = 'a'",
).fetchone() is not None
Output from the test:
$ pytest tests/test_auth.py
=========================================== FAILURES
============================================
_________________________________________ test_register
_________________________________________
client = <FlaskClient <Flask 'flaskr'>>, app = <Flask 'flaskr'>
def test_register(client, app):
assert client.get('/auth/register').status_code == 200
response = client.post(
'/auth/register', data={'username': 'a', 'password': 'a'}
, follow_redirects=True)
print(f'{response.status=}')
print(f'{response.response=}')
for x in response.response:
print(x)
> assert response.headers["Location"] == "/auth/login"
tests/test_auth.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.11/site-
packages/werkzeug/datastructures/headers.py:83: in __getitem__
return self._get_key(key)
_ _ _ _ _ _ _ _ _ _ _ _ _
self = Headers([('Content-Type', 'text/html; charset=utf-8'),
('Content-Length', '960'), ('Vary', 'Cookie')])
key = 'Location'
def _get_key(self, key: str) -> str:
ikey = key.lower()
for k, v in self._list:
if k.lower() == ikey:
return v
> raise BadRequestKeyError(key)
E werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
venv/lib/python3.11/site-packages/werkzeug/datastructures/headers.py:97: BadRequestKeyError
本文标签: pythonTesting a flaskWTForms app that uses csrf token (pytest)Stack Overflow
版权声明:本文标题:python - Testing a flask-WTForms app that uses csrf token (pytest) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741271826a2369441.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论