Testing Flask Apps
Testing is the practice of writing code that automatically checks your app behaves correctly — confirming each route returns the right status and content — so you catch bugs before your users ever see them.
Learn Testing Flask Apps in our free Flask course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Flask course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll send requests with Flask's test client, write tests with pytest, and use a fixture to keep every test clean and repeatable.
The test client is a fake browser built into Flask. Calling app.test_client() gives you an object whose .get() and .post() methods send requests to your routes in memory — no running server required.
Each request returns a response object with a status_code (200 means OK, 404 means not found) and a data attribute holding the body bytes.
With pytest you write functions named test_something() and use plain assert statements. Run pytest in your terminal and it finds and runs every test automatically, reporting which passed and which failed.
Repeating app.test_client() in every test is tedious. A fixture — a function marked @pytest.fixture — builds the client once, and pytest passes it into any test that asks for it by name. Pair this with your create_app() factory and a testing config.
Because the fixture rebuilds the app for every test, each one starts from a clean slate — no leftover state from a previous test can cause confusing failures.
Complete the test below. Replace each ___ so it creates a client, sends a GET request, and asserts the result.
❌ TypeError: a bytes-like object is required, not 'str'
You compared response.data (bytes) to a normal string. Use a bytes literal like b"Hello" or decode with response.data.decode() .
pytest only finds functions whose names start with test_ in files named test_*.py . Check your naming.
Write a test that submits form data to a POST route and checks the response.
Lesson 20 complete — your app is tested!
You can now use the test client, write pytest tests, and share setup with fixtures. Tests are your safety net — they let you change code without fear of breaking what already works.
🚀 Up next: Deploying Flask — take your app off your laptop and put it on the internet with a production server.
Practice quiz
How do you create Flask's test client?
- Flask.client()
- app.test_client()
- app.client()
- test_client(app)
Answer: app.test_client(). Calling app.test_client() gives you a fake browser that sends requests to your routes in memory.
Which attribute holds a response's HTTP status code?
- response.status_code
- response.code
- response.status
- response.http
Answer: response.status_code. response.status_code is 200 for OK and 404 for not found.
What type is response.data from the test client?
- A dict
- A string
- Bytes
- A list
Answer: Bytes. response.data holds the body as bytes, so compare it against a bytes literal like b'Hello'.
Which name prefix does pytest use to discover test functions?
- check_
- spec_
- verify_
- test_
Answer: test_. pytest collects any function whose name starts with test_.
Which decorator marks a reusable pytest fixture?
- @pytest.setup
- @pytest.fixture
- @fixture
- @pytest.provide
Answer: @pytest.fixture. A fixture is a function marked with @pytest.fixture; pytest injects it by name into tests.
How do you send a GET request with the test client?
- client.get('/')
- client.fetch('/')
- client.request('/')
- client.GET('/')
Answer: client.get('/'). client.get('/') sends a GET request to the given path and returns the response.
Which method submits form data to a POST route in a test?
- client.send(data=...)
- client.form(...)
- client.post('/r', data={...})
- client.submit(...)
Answer: client.post('/r', data={...}). client.post('/route', data={...}) sends form fields via the data argument.
Why do test-client requests run so fast?
- They skip assertions
- They cache responses
- They reuse one socket
- Nothing touches the network; they run in memory
Answer: Nothing touches the network; they run in memory. The test client never starts a real server, so tests run in milliseconds.
What command runs all your pytest tests?
- pytest
- python -m unittest
- flask test
- run pytest --all
Answer: pytest. Running 'pytest' in your terminal discovers and runs every test_ function.
How can you read a JSON response body in a test?
- response.json_body
- response.body()
- response.get_json()
- response.parse()
Answer: response.get_json(). response.get_json() parses and returns the JSON payload as a Python object.