Pytest-flask is a plugin for the Pytest framework, which provides a set of tools to test an application using the Flask framework.
You can install the plugin using the command pip
:
pip install pytest-flask
Configure Pytest-Flask
First of all, you’re going to create what we call a fixture to configure the application for testing.
Let’s consider the app.py
file, which contains the Flask application and simply returns the string Hello, World!
to the index
route.
from flask import Flask
def create_app(config):
app = Flask(__name__)
app.config.from_object(config)
@app.route('/index')
def index():
return 'Hello, World!'
return app
You can then create the conftest.py
file in a dedicated test directory that will contain the fixture. The fixture will then be able to be called in each test that requires the application.
import pytest
from app import create_app
@pytest.fixture
def client():
app = create_app({"TESTING": True})
with app.test_client() as client:
yield client
Now it’s time to start testing our application’s functionality. So, we’ve set up an endpoint /index,
which returns Hello, World!
.
So, you’re going to create a file named test_app.py
in the tests/
directory to create all of our tests.
Test the Return Code
Pytest enables us to test the status code of the HTTP request. This will determine the result of a request or indicate an error. You can find details about status codes in the Mozilla documentation.
Here are some of the most common ones:
200: request successful
401: authentication error
403: access denied
404: page not found
504: server timed out
Let’s get started. Now you know the status codes, we can set up a test that will check that the status code for our request is 200.
from tests.conftest import client
def test_should_status_code_ok(client):
response = client.get('/index')
assert response.status_code == 200
Let’s analyze each line:
from tests.conftest import client
: Import the fixture that contains the application.def test_should_status_code_ok(client)
: Call theclient
fixture by declaring it as an argument.response = client.get('/index')
: Send an HTTP GET request to the application with the path passed as an argument.assert response.status_code == 200
: Using the return value from theclient.get()
function, we can retrieve the HTTP status code using thestatus_code
attribute. Now we can check that the code equals 200.
Test the Returned Data
It’s really useful to be able to test the code returned by the request to check the result, but it’s even more handy to be able to check the contents of the request.
How do we do it?
Pytest provides functions to check the contents of the data. As we did with the previous test, we’re going to look for the data in the response to the client.get()
function. However, the data needs to be decoded before we can check it against the expected value.
Here’s the test that we can set up to check the contents of our endpoint:
def test_should_return_hello_world(client):
response = client.get('/index')
data = response.data.decode() #Decodes the request data
assert data == 'Hello, World!'
Use POST Requests
In most applications, the majority of features require a user to be logged in. We therefore need our test client to log in and out. To do this, you’ll need to send a POST
request and include login details as parameters (username and password).
You can use the post()
method to do this. Here’s an example:
username = 'testUser'
password = 'testPassword'
client.post('/login', data={'username' : username, 'password' : password})
In the first argument you need to provide the path, and in the second, a dictionary that contains the data required for your request.
Now that you know how to use a POST
request to log a user in, you can use the same method for other requests of this type.
Over to You!
Have another look at the source code for a project using the Flask framework so you can practice setting up unit tests using pytest-flask. Watch the video below to learn more about the application:
Your Mission:
Write a test plan for this project.
Create a sequence of tests for the whole project using pytest-flask.
Before starting to create your sequence of tests, you can watch this unit testing example for the project to give you a starting point:
Find a suggested solution on GitHub!
Let’s Recap!
Pytest can also create and execute tests for a Flask project.
The pytest-flask plugin provides a set of useful tools to test Flask applications and extensions.
The
status_code
attribute provides the HTTP return code for the request.You can retrieve the data returned by the request using the
data
attribute. This means that you can decode and then check the contents of the response to validate your testing.The test client provides the
post()
method to simulate aPOST
request. You can provide data in the method’s parameters.
Have you got all that? Excellent! Now we’re going to tackle testing using the Django framework. We’re not done, there’s a lot of great stuff coming up in the next chapter.