Open H4dr1en opened 9 months ago
To help Streamlit prioritize this feature, react with a 👍 (thumbs up emoji) to the initial post.
Your vote helps us identify which enhancements matter most to our users.
Also would be cool to if AppTest could support st.image, st.video, st.download_button
For anybody else looking for a simple workaround until the file_uploader is added to the supported widgets, here is a solution I now use:
App file:
import streamlit as st
import pandas as pd
st.title('Hello World')
file = st.file_uploader('Upload a file')
if file is not None:
df = pd.read_csv(file)
st.write(df)
else:
st.write('Please upload a file')
Test file with mocking using the unittest.mock:
from streamlit.testing.v1 import AppTest
from unittest.mock import MagicMock, patch
import pandas as pd
from io import BytesIO
def test_loadpage():
at = AppTest(f"app.py", default_timeout=100)
at.run()
assert at.markdown[0].value == 'Please upload a file'
@patch("streamlit.file_uploader")
def test_loadmockedpage(mock_file: MagicMock):
mock_file.return_value = None
at = AppTest(f"app.py", default_timeout=100)
at.run()
assert at.markdown[0].value == 'Please upload a file'
@patch("streamlit.file_uploader")
def test_mockupload(mock_file: MagicMock):
expected_file = "pathto.csv"
with open(expected_file, "rb") as f:
mock_file.return_value = BytesIO(f.read())
at = AppTest(f"app.py", default_timeout=100)
at.run()
expected_df = pd.read_csv(expected_file)
assert at.dataframe[0].value.equals(expected_df)
Contrary to how mocks work normally (point to where the original is used) you have to patch the file_uploader in streamlit.
@JuliaS92 Is there a way to do the same functionality with pytest?
@shamikbosefj This works when running the tests with pytest. Pytest seems to have it's own module, that uses unittest under the hood if I get this right. So if you want to avoid unittest.mock that should be doable.
Thanks, @JuliaS92 ! I'll try that one out and update here if I can get it working
@JuliaS92 One quick question. I'm trying to upload an image file, which runs through some processing and updates the app. I can see that the file is being uploaded, but the app values don't change according to the test suite. Any ideas what I might be doing wrong?
#streamlit app
def process_image(uploaded_file):
Do something with file
update app
UPDATE: The mocked snippet above works great! I had to reinitialize the containers within the testing script after app.run()
as follows
tab_1 = at.tabs[0]
at.run()
tab_1 = at.tabs[0]
Checklist
Summary
Requesting support for the file_upload widget in AppTest
Why?
It blocks testing the rest of the app as its logic depends on the uploaded file
How?
Add support for the file_upload widget in AppTest
Additional Context
No response