Testing Streamlit: `TypeError: object supporting the buffer API required` when running `AppTest`

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

It turned out that AppTest.from_file expects a string path. In other words, I need to convert the Path to a string.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.