liveBook · Manning

Pytest

As explained in Build Python Web Apps with Streamlit

pytest is a Python testing framework for writing and running tests with concise test functions, assertions, fixtures, and plugins.

A Streamlit app can look fine until unexpected data or a code change exposes a bug. pytest is a Python framework for writing and running automated checks, so you can catch failures before users do. section 11.0 section 11.2.3

Start with one test

Install pytest with `pip install pytest`. In `test_example.py`, define `add(x, y)` and a `test_add()` function that checks `assert add(2, 3) == 5`. Run `pytest -v` in that file’s directory. pytest discovers the test and reports whether it passed. section 11.2.3

Build useful tests one check at a time:

  • Name test functions with a `test_` prefix. Use `assert` to compare actual results with expected results, including cases such as an empty search result. section 11.3.2
  • Put repeated setup in a function marked `@pytest.fixture`. A test receives that setup by naming the fixture as a parameter. section 11.3.2
  • Use `unittest.mock.patch` to replace an external request when unit-testing backend behavior. Check both the returned data and how the request was called. section 11.3.2
Listing 11.5 Backend unit tests
import pytest
from unittest.mock import patch, Mock
from backend import Backend, SEARCH_URL
from mock_data import MOCK_MOVIES, MOCK_RESULTS

@pytest.fixture
def backend():
  api_key = "test_api_key"
  return Backend(api_key)

@patch('requests.get')
def test_search_movies_success(mock_get, backend):
  mock_response = Mock()
  mock_response.json.return_value = {'results': MOCK_MOVIES}
  mock_get.return_value = mock_response

  results = backend.search_movies("test query")

  mock_get.assert_called_once_with(
    SEARCH_URL,
    params={"api_key": backend.api_key, "query": "test query"}
  )
  assert len(results) == len(MOCK_MOVIES)
  for _id, movie in MOCK_RESULTS.items():
    assert _id in results
    assert results[_id]["title"] == movie["title"]

A complete backend test combines a fixture, a mocked HTTP response, and assertions about the search request and its results. section 11.3.2

When a test fails, read the failing assertion and pytest’s expected-versus-actual output. An intentionally wrong expectation of `[]` reveals that an empty movie search returns `{}`. A frontend test catches a quieter bug: the display reads a missing `rating` field instead of `vote_average`, showing `N/A` rather than the movie’s rating. Fix the code and run `pytest -v` again. Passing isolated tests are useful, but they do not establish that frontend and backend work together; integration tests check that connection. section 11.3.3 section 11.4.2

How Build Python Web Apps with Streamlit covers it

How deep it goes
Works through assertions, reusable fixtures, mocked unit tests, verbose runs, and failure output; treats integration and end-to-end tests as additional layers.
Examples
Uses an addition test, mocked movie-search backend tests, and a frontend rating failure to demonstrate passing tests and debugging.
What it assumes
Assumes basic Python functions and terminal use while introducing pytest installation, test naming, assertions, and fixtures through examples.
What you can do after
Apply it via pytest to run backend and frontend tests, inspect failures, fix defects, and rerun the checks.
How it connects
Connects unit testing to fixtures, assertions, mocking, Streamlit AppTest, integration testing, and end-to-end testing.

Also explained in

Compare how 11 books explain pytest →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build Python Web Apps with Streamlit. The section links point to the parts of the book it draws on.