After having explored and experimented with Streamlit the next step is to refactor and mature my code.
So now i’m wondering. What’s best practice for testing parts of my code? I guess I would start to refactor some of my code into component functions. A hypothetical example is
import streamlit as st
def write_author(author: str):
st.write(f"Author: {author}")
How can I use pytest to test this?
One option is pytest-selenium. But that is cumbersome, error prone and slow to do.
Unfortunately, there’s nothing particularly awesome or magical for doing this (unless you’re quite enamored of testing frameworks)!
For our code, we use a mix of unit tests (via pytest and Jest for Python and JavaScript/TypeScript, respectively), and end-to-end tests via Cypress.
If you download the Streamlit repo, you can see our streamlit/scripts/run_e2e_tests.sh script that automates the end-to-end testing process. This script iterates all tests in the streamlit/e2e/ folder.
Each test is comprised of two files: a streamlit/e2e/scripts/{test_name}.py Python file, and a streamlit/e2e/specs/{test_name}.spec.ts TypeScript file.
For each test, that test’s Python file implements a barebones Streamlit app that uses the functionality being tested, and its TypeScript component asserts that the resultant web page looks like it should.
The run_e2e_tests script does two things for each test:
streamlit run e2e/scripts/{test_name}.py. This runs the Python component via streamlit
yarn cy:run --spec e2e/specs/{test_name}.spec.ts This fires up Cypress and tells it to run the corresponding TypeScript test component.
You can use Cypress to automate interaction, to test that the interactive bits of your frontend cause your app to re-run and update in the expected way.
Thanks for you feedback. If I could somehow st.get_frontend_document() from the frontend it would be rather easy to setup a test framework in the backend (i believe). I will post a feature request.
from typing import List
import awesome_streamlit as ast
from awesome_streamlit.testing.models import (
TesTItem, # Special Capitalization is due to PyTest
)
def test_items_collector() -> List[TesTItem]:
"""A function to collect a list of test items based on a set of hardcode testitems"""
return [
TesTItem(
name="Spreadsheet",
location=(
"https://raw.githubusercontent.com/MarcSkovMadsen/awesome-streamlit/master"
"/src/pages/gallery/contributions/marc_skov_madsen/spreadsheet.py"
),
)
]
ast.testing.test_runner_app.write(test_items_collector=test_items_collector)
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.