Defining the pytest fixtures
Fixtures are used in pytest to prepare the context in which a test should be executed, preparing it and cleaning it at the end. The application fixture is expected by pytest-flask, as seen in the documentation. The plugin generates a client fixture that we can use to send requests in test mode. We see this fixture in action in the thoughts_fixture fixture, which generates three thoughts through the API and deletes everything after our test has run.
The structure, simplified, is as follows:
- Generate three thoughts. Store its thought_id:
@pytest.fixture
def thought_fixture(client):
thought_ids = []
for _ in range(3):
thought = {
'text': fake.text(240),
}
header = token_validation.generate_token_header(fake.name(),
PRIVATE_KEY)
headers = {
'Authorization': header,
}
response = client.post('/api/me/thoughts/', data=thought,
headers=headers)
assert http.client.CREATED == response.status_code
result = response.json
thought_ids.append(result['id'])
- Then, add yield thought_ids to the test:
yield thought_ids
- Retrieve all thoughts and delete them one by one:
# Clean up all thoughts
response = client.get('/api/thoughts/')
thoughts = response.json
for thought in thoughts:
thought_id = thought['id']
url = f'/admin/thoughts/{thought_id}/'
response = client.delete(url)
assert http.client.NO_CONTENT == response.status_code
Note that we use the faker module to generate fake names and text. You can check its full documentation at https://faker.readthedocs.io/en/stable/. It is a great way of generating random values for your tests that avoid reusing test_user and test_text over and over. It also helps to shape your tests, by checking the input independently and not blindly copying a placeholder.
This way, we also use tests to validate that we can use our microservice as a complete service, without tricking ourselves into hacking our way to perform common operations.
Also note the usage of the client fixture, which is provided by pytest-flask.