I am trying to test my streamlit app with the AppTest
class, but run into issues from the get-go. Here are the file contents that produce my error for a very simple app:
mwe_app.py
import streamlit as st
st.write("Hello, world! ")
tests/conftest.py
import pytest
from pathlib import Path
from streamlit.testing.v1 import AppTest
APP = Path(__file__).absolute().parent.parent.joinpath("my_project", "mwe_app.py")
@pytest.fixture
def app_path():
yield APP
@pytest.fixture
def test_app():
yield AppTest.from_file(APP)
tests/test_app.py
def test_can_find_app(app_path):
assert app_path.exists()
def test_app_startup(test_app):
test_app.run()
assert not test_app.exception
When I run the tests with pytest tests
I get the following error:
.F [100%]
====================================================================================================== FAILURES =======================================================================================================
__________________________________________________________________________________________________ test_app_startup ___________________________________________________________________________________________________
test_app = AppTest(
_script_path=PosixPath('/home/***/dev/***/***/***/mwe_app.py'),
default_timeout=3,
session_state={$$STREAMLIT_INTERNAL_KEY_TESTING: {}},
_tree={
}
)
def test_app_startup(test_app):
> test_app.run()
tests/test_app.py:5:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.11/site-packages/streamlit/testing/v1/app_test.py:379: in run
return self._tree.run(timeout=timeout)
.venv/lib/python3.11/site-packages/streamlit/testing/v1/element_tree.py:1840: in run
return self._runner._run(widget_states, timeout=timeout)
.venv/lib/python3.11/site-packages/streamlit/testing/v1/app_test.py:339: in _run
self._tree = script_runner.run(
.venv/lib/python3.11/site-packages/streamlit/testing/v1/local_script_runner.py:123: in run
require_widgets_deltas(self, timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
runner = LocalScriptRunner(forward_msg_queue=<streamlit.runtime.forward_msg_queue.ForwardMsgQueue object at 0x7f3c6f6335d0>, sc...ker.base.Signal object at 0x7f3c6f66ec10>, _script_thread=<Thread(ScriptRunner.scriptThread, stopped 139897542981184)>)
timeout = 3
def require_widgets_deltas(runner: LocalScriptRunner, timeout: float = 3) -> None:
"""Wait for the given ScriptRunner to emit a completion event. If the timeout
is reached, the runner will be shutdown and an error will be thrown.
"""
t0 = time.time()
while time.time() - t0 < timeout:
time.sleep(0.001)
if runner.script_stopped():
return
# If we get here, the runner hasn't yet completed before our
# timeout. Create an error string for debugging.
err_string = f"AppTest script run timed out after {timeout}(s)"
# Shutdown the runner before throwing an error, so that the script
# doesn't hang forever.
runner.request_stop()
runner.join()
> raise RuntimeError(err_string)
E RuntimeError: AppTest script run timed out after 3(s)
.venv/lib/python3.11/site-packages/streamlit/testing/v1/local_script_runner.py:175: RuntimeError
================================================================================================== warnings summary ===================================================================================================
tests/test_app.py::test_app_startup
/home/***/dev/***/***/.venv/lib/python3.11/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread ScriptRunner.scriptThread
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
File "/usr/lib/python3.11/threading.py", line 982, in run
self._target(*self._args, **self._kwargs)
File "/home/***/dev/***/***/.venv/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 307, in _run_script_thread
self._run_script(request.rerun_data)
File "/home/***/dev/***/***/.venv/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 430, in _run_script
pages = source_util.get_pages(main_script_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/***/dev/***/***/.venv/lib/python3.11/site-packages/streamlit/source_util.py", line 124, in get_pages
main_page_script_hash = calc_md5(main_script_path_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/***/dev/***/***/.venv/lib/python3.11/site-packages/streamlit/util.py", line 176, in calc_md5
h.update(b)
TypeError: object supporting the buffer API required
warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=============================================================================================== short test summary info ===============================================================================================
FAILED tests/test_app.py::test_app_startup - RuntimeError: AppTest script run timed out after 3(s)
1 failed, 1 passed, 1 warning in 3.17s
requirements.txt
alabaster==0.7.16
altair==5.3.0
asttokens==2.4.1
attrs==23.2.0
Babel==2.15.0
black==24.4.2
blinker==1.8.2
cachetools==5.3.3
cattrs==23.2.3
certifi==2024.2.2
cffi==1.16.0
cfgv==3.4.0
charset-normalizer==3.3.2
click==8.1.7
cognite-sdk==7.43.2
comm==0.2.2
cryptography==42.0.7
debugpy==1.8.1
decorator==5.1.1
distlib==0.3.8
docutils==0.20.1
esbonio==0.16.4
executing==2.0.1
fastjsonschema==2.19.1
filelock==3.14.0
flake8==7.0.0
gitdb==4.0.11
GitPython==3.1.43
gunicorn==22.0.0
identify==2.5.36
idna==3.7
imagesize==1.4.1
iniconfig==2.0.0
ipykernel==6.29.4
ipython==8.24.0
jedi==0.19.1
Jinja2==3.1.4
jsonschema==4.22.0
jsonschema-specifications==2023.12.1
jupyter_client==8.6.1
jupyter_core==5.7.2
lsprotocol==2023.0.1
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib-inline==0.1.7
mccabe==0.7.0
mdit-py-plugins==0.4.1
mdurl==0.1.2
msal==1.28.0
mypy==1.10.0
mypy-extensions==1.0.0
myst-parser==3.0.1
nbformat==5.10.4
nest-asyncio==1.6.0
nodeenv==1.8.0
numpy==1.26.4
oauthlib==3.2.2
packaging==24.0
pandas==2.2.2
parso==0.8.4
pathspec==0.12.1
pexpect==4.9.0
pillow==10.3.0
platformdirs==4.2.1
plotly==5.22.0
pluggy==1.5.0
pre-commit==3.7.1
prompt-toolkit==3.0.43
protobuf==4.25.3
psutil==5.9.8
ptyprocess==0.7.0
pure-eval==0.2.2
pyarrow==16.1.0
pycodestyle==2.11.1
pycparser==2.22
pydeck==0.9.1
pydocstyle==6.3.0
pyflakes==3.2.0
pygls==1.3.1
Pygments==2.18.0
PyJWT==2.8.0
pyspellchecker==0.8.1
pytest==8.2.0
python-dateutil==2.9.0.post0
pytz==2024.1
PyYAML==6.0.1
pyzmq==26.0.3
referencing==0.35.1
requests==2.31.0
requests-oauthlib==1.3.1
rich==13.7.1
rpds-py==0.18.1
-e git+ssh://git@github.com/***/***.git@1a0a4ea5272ecffd68a70cf2e77cacdfa22a53cc#egg=***
six==1.16.0
smmap==5.0.1
snowballstemmer==2.2.0
Sphinx==7.3.7
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.8
sphinxcontrib-devhelp==1.0.6
sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
stack-data==0.6.3
streamlit==1.34.0
tenacity==8.3.0
toml==0.10.2
toolz==0.12.1
tornado==6.4
traitlets==5.14.3
typing_extensions==4.11.0
tzdata==2024.1
urllib3==2.2.1
virtualenv==20.26.2
watchdog==4.0.0
wcwidth==0.2.13
XlsxWriter==3.2.0