I have a flask app
and I'm trying to improve my pytest
tests by using random data with hypothesis
.
I have a fixture in conftest.py
that yields a flask test client:
@pytest.fixture(scope="session", name="client", autouse=True)
def fixture_client() -> FlaskClient:
"""Yield a flask test client."""
app.testing = True
app.secret_key = 'some_secret_key'
# do something else before yielding
yield app.test_client()
# do some teardown
Then in my auth_test.py
I have a function that I use for multiple tests:
def _test_failed_registration(
client: FlaskClient,
flash_message,
name=ValidUser.name,
password=ValidUser.password,
confirm=ValidUser.password,
email=ValidUser.email
):
"""Common logic for testing failed registration."""
with client:
client.get("/")
client.get(url_for("auth.register"))
data = {
"csrf_token": g.csrf_token,
"name": name,
"password": password,
"confirm": confirm,
"email": email}
response = client.post("/auth/register", data=data)
assert response.status_code == 200
assert flash_message in unescape(response.text)
assert "Registration request sent. Please contact an admin." \
not in response.text
For example one of the tests checks for a short username:
@settings(max_examples=20)
@given(name=st.text(min_size=1, max_size=USER_MIN_LENGTH - 1))
@example(name="")
def test_failed_registration_short_name(client: FlaskClient, name):
"""test_failed_registration_short_name"""
if not name:
flash_message = "Username is required!"
else:
flash_message = (f"Username must be between {USER_MIN_LENGTH} and " +
f"{USER_MAX_LENGTH} characters!")
_test_failed_registration(client=client,
name=name,
flash_message=flash_message)
This is working but the my problem is that I always have to pass the client
fixture when calling _test_failed_registration
, although I don't need it.
Is there a way to avoid this? Something like:
def _test_failed_registration(
flash_message,
name=ValidUser.name,
password=ValidUser.password,
confirm=ValidUser.password,
email=ValidUser.email
):
"""Common logic for testing failed registration."""
client = ?????
with client:
# same logic as before
...
@settings(max_examples=20)
@given(name=st.text(min_size=1, max_size=USER_MIN_LENGTH - 1))
@example(name="")
def test_failed_registration_short_name(name):
"""test_failed_registration_short_name"""
# same logic
...
_test_failed_registration(name=name,
flash_message=flash_message)
I'm trying to simplify the code so using wrappers and closure seems like overcomplicating things.
I tried using request
from pytest, which works, but now I have to pass along the request:
_test_failed_registration(request=request,
name=name,
flash_message=flash_message)
I tried decorating with @pytest.mark.usefixtures("client")
but I don't know how to access the client now:
@pytest.mark.usefixtures("client")
def _test_failed_registration(
flash_message,
name=ValidUser.name,
password=ValidUser.password,
confirm=ValidUser.password,
email=ValidUser.email
):
"""Common logic for testing failed registration."""
client = ?????
with client:
# same logic as before
...