A Streamlit app can look right until a user enters a search term and clicks a button. AppTest lets a Python test run the app, simulate those actions, and inspect its output without opening a browser. section 11.4
A frontend test follows a short cycle:
- Create a runnable app with AppTest.from_file("frontend.py"). Set test secrets if the app needs them, then call run() to start it. section 11.4.1
- Find elements by type, such as at.sidebar.text_input or at.sidebar.button. Use set_value(...) or click(), followed by run() to trigger a rerun. section 11.4.1 section 11.8
- Assert what changed in session_state and in rendered elements such as expanders or markdown. section 11.4.1
Listing 11.7 Testing the frontend
import pytest
from unittest.mock import patch
from streamlit.testing.v1 import AppTest
from mock_data import MOCK_RESULTS
class MockBackend:
@staticmethod
def get_poster_url(path):
return "https://mock-image-server.com/poster.jpg"
def __init__(self, api_key):
self.api_key = api_key
def search_movies(self, query):
return MOCK_RESULTS
@pytest.fixture
def setup_app():
at = AppTest.from_file("frontend.py")
at.secrets["api_key"] = "test_api_key"
return at
@patch("backend.Backend", MockBackend)
def test_initial_state(setup_app):
at = setup_app
at.run()
# Check if sidebar has search input field and button
assert len(at.sidebar.text_input) == 1
assert len(at.sidebar.button) == 1
assert "Search" in at.sidebar.button[0].label
# Check that results are not visible initially
assert "results" not in at.session_state
assert len(at.expander) == 0
This complete starting-state test shows a pytest fixture creating the app, supplying a test API key, and checking the sidebar before any search. A patched backend keeps this frontend test independent of the real backend. section 11.4.1
Test a search
After at.run(), enter a query with at.sidebar.text_input[0].set_value("test movie").run(), then press at.sidebar.button[0].click().run(). With a mock backend returning known results, assert that at.session_state["results"] matches those results and that the number of at.expander elements matches the number of movies. A separate display test checks movie overviews and ratings in at.markdown. section 11.4.1
AppTest also supports an end-to-end check. Run the app without replacing its backend, search for a real movie, and assert that results and their expanders appear. This checks the frontend, backend, and external API together rather than isolating the frontend. section 11.2.2 section 11.6
