Hey, @jcarroll, first off, I want to thank you for taking the time to review this. I really do appreciate it.
Hopefully I provide enough detail for you.
Context
As mentioned in our previous discussion, I am trying out AppTest
so that I can implement native testing with Streamlit. (It’s great that this is a feature by the way).
Issue
The problem I am running into is that I my dashboard uses API keys to reach out to services to provide some functionality. When I first started to write my tests, everything was working fine locally. Then, in a separate test repo on GitHub, I applied the same exact tests but they were failing, After some time, I found out that because the .streamlit/secrets.toml
was missing, it couldn’t access the key to continue the tests.
Project Setup
Here is my main repository. The file structure is set where the components/
directory houses certain areas of the dashboard in classes that are then imported to the main streamlit_app.py
file. I’m slowly starting to implement classes for organization. Anyway, in the main streamlit_app.py
file, I am importing the StadiumMapSection
class from components/stadiums_map_section.py
and instantiated it on line 18.
Errors
When I run the pytest using this command (locally or not): pytest --cov=streamlit_app tests/ -v
, without the .streamlit/secrets.toml
being present, the coverage returns:
---------- coverage: platform darwin, python 3.11.6-final-0 ----------
Name Stmts Miss Cover Missing
------------------------------------------------
streamlit_app.py 229 215 6% 19-726
------------------------------------------------
TOTAL 229 215 6%
So it’s basically skipping the entire file. When I place the the secrets file back in the directory, all the tests pass with no issue.
Here is more output from the failures:
______________________________________________________________________________________ test_title_area ________________________
def test_title_area():
> assert "Premier League Statistics / 2023-24" in at.title[0].value
tests/test_streamlit_app.py:7:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ElementList(), idx = 0
def __getitem__(self, idx: int | slice) -> El | ElementList[El]:
if isinstance(idx, slice):
return ElementList(self._list[idx])
else:
> return self._list[idx]
E IndexError: list index out of range
venv/lib/python3.11/site-packages/streamlit/testing/v1/element_tree.py:229: IndexError
_______________________________________________________________________________________ test_tab_one __________________________
def test_tab_one():
> assert at.tabs[0].subheader[0].value == "League Statistics"
E IndexError: list index out of range
tests/test_streamlit_app.py:12: IndexError
Attempts
I looked at your two suggestions and I tried implementing a mock test with unitest.patch
like you mentioned but I could not get it working. (I’ve never used this before).
I tried a couple of variations:
from streamlit.testing.v1 import AppTest
from unittest.mock import patch
at = AppTest.from_file("streamlit_app.py", default_timeout=1000).run()
def test_title_area():
assert "Premier League Statistics / 2023-24" in at.title[0].value
assert "Current Round: " in at.subheader[0].value
@patch('streamlit.secrets', return_value={"mapbox": {"mapbox_key": "fake_mapbox_key"}})
def test_tab_one():
assert at.tabs[0].subheader[0].value == "League Statistics"
assert at.tabs[0].subheader[1].value == "Current Standings"
assert at.tabs[0].subheader[2].value == "Location of Stadiums"
and
@patch('components.stadiums_map_section.StadiumMapSection.mapbox_access_token', 'fake_mapbox_key')
def test_tab_one():
assert at.tabs[0].subheader[0].value == "League Statistics"
assert at.tabs[0].subheader[1].value == "Current Standings"
assert at.tabs[0].subheader[2].value == "Location of Stadiums"
but neither worked. I’m not even sure if I am on the right path to be honest.
With more information now, I’m curious to know if you think there is a better option or method of doing this.