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.