FlaskTester Documentation
This is the documentation for the fixtures and support classes provided
by FlaskTester.
Fixtures
The package provides two fixtures:
ft_authenticatorfor app authentication, which depends on environment variables:FLASK_TESTER_ALLOWspace-separated list of allowed authentication schemes, defaults to bearer basic param none.FLASK_TESTER_AUTHcomma-separated list of login:password credentials, defaults to empty.FLASK_TESTER_USERuser login parameter forparampassword authentication, defaults to USER.FLASK_TESTER_PASSuser password parameter forparampassword authentication, defaults to PASS.FLASK_TESTER_LOGINuser login parameter forfakeauthentication, defaults to LOGIN.FLASK_TESTER_TPARAMtoken parameter fortparamtoken authentication, defaults to AUTH.FLASK_TESTER_BEARERbearer scheme forbearertoken authentication, defaults to Bearer.FLASK_TESTER_HEADERheader name for forheadertoken authentication, defaults to Auth.FLASK_TESTER_COOKIEcookie name for forcookietoken authentication, defaults to auth.FLASK_TESTER_PTYPEdefault type of parameters,dataorjson, defaults to data.FLASK_TESTER_LOG_LEVELlog level for module, defaults to NOTSET.
The fixture has 3 useful methods:
setPassto associate a password to a user, set to None to remove credential.auth.setPass("susie", "<susie-incredible-password>")
setTokento associate a token to a user, set to None to remove credential.auth.setToken("moe", "<moe's-token-computed-or-obtained-from-somewhere>")
setCookieto add a cookie to a user, set value to None to remove cookie.auth.setCookie("rosalyn", "lang", "en_US")
ft_clientfor app testing, which depends on the previous fixture and is configured from two environment variables:FLASK_TESTER_APPtells where to find the application, which may be the:URL of the running application for external tests, eg http://localhost:5000. The application is expected to be already running when the test is started.
Package (filename without
.py) to be imported for the application.for pkg:name, name is the application in pkg.
for pkg only, look for app as app, application, create_app, make_app.
in both cases, name is called if callable and not a Flask application.
If not set, the defaults to app, which is to behave like Flask.
FLASK_TESTER_DEFAULTdefault login for authentication, defaults to None.
The fixture then provides test methods to issue test requests against a Flask application:
requestgeneric request withlogin,auth,statusendcontentextensions.For instance, the following sumits a
POSTon path/userswith one JSON parameter, as user calvin using basic authentication, expecting status code 201 and some integer value (content regex) in the response body:res = app.request("POST", "/users", 201, r"\d+", json={"username": "hobbes"}, login="calvin", auth="basic") assert res.is_json and "uid" in res.json uid = res.json["uid"]
The authentication data, here a password, must have been provided to the authenticator.
Direct parameters from
pydanticanddataclassclasses are supported and converted to JSON.get post put patch deletemethods with the same extensions.Submit a
GETrequest to path/statsauthenticated as hobbes, expecting response status 200:app.get("/stats", 200, login="hobbes")
setHookallows to add a hook executed onsetPass. The typical use case is to load a token when new credentials are provided. As with other methods, None is used for removal.def authHook(client: Client, username: str, password: str|None): if password: res = client.post("/login", 201, login=username, auth="param") client.setToken(username, res.json["token"]) else: client.setToken(username, None)
Moreover,
setPass,setTokenandsetCookieare forwarded to the internal authenticator.
Authenticator environment variables can be set from the pytest Python test file by
assigning them through os.environ.
The typical use case is to define a local fixture, set the authentication and other data, and then proceed with it:
import os
import pytest
from FlaskTester import ft_client, ft_authenticator
import secret
os.environ.update(FLASK_TESTER_ALLOW="basic param none")
@pytest.fixture
def app(ft_client):
ft_client.setPass("calvin", secret.PASSES["calvin"])
ft_client.setCookie("calvin", "lang", "en")
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
ft_client.setCookie("hobbes", "lang", "fr")
yield ft_client
def test_app(app):
# requires an authentication
app.get("/authenticated", 401, login=None)
app.get("/authenticated", 200, "Hello", login="calvin")
app.get("/authenticated", 200, "Bonjour", login="hobbes")
# only allowed to calvin
app.get("/only-admin", 401, login=None)
app.get("/only-admin", 200, "administrateur", login="calvin")
app.get("/only-admin", 403, "not in group", login="hobbes")
# no authentication required, but depends on lang
app.get("/open", 200, "Hello", login="calvin", auth="none")
app.get("/open", 200, "Bonjour", login="hobbes", auth="none")
app.get("/open", 200, "Guten Tag", login=None)
Classes
The implementation of these fixtures is based on five classes, see the API documentation for further details:
Authenticatorclass to store test credentials.RequestFlaskResponseclass to turn arequestsresponse into a Flask-looking response, with the following attributes:status_code,data,text,headers,cookies,is_jsonandjson.Clientabstract class to run test, with two implementations.FlaskClientimplementation class for internal (test_client) tests.RequestClientimplementation class for external (real HTTP) tests.
Exceptions
The following exceptions are defined and may be raised:
FlaskTesterErrorroot class for exceptions.AuthErrorauthentication-related errors.
See Also, or Not
Flask Testing an unmaintained old-style unit test for Flask 1.x, without authentication help.