Skip to content

Commit c17cc66

Browse files
authored
Merge pull request #94 from jcharkow/add_tests
test: add initial GUI test
2 parents d701e1e + fc80ccd commit c17cc66

File tree

6 files changed

+162
-6
lines changed

6 files changed

+162
-6
lines changed

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: continuous-integration
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
os: [ubuntu-latest]
11+
# Requirements file generated with python=3.11
12+
python-version: ["3.11"]
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python ${{ matrix.python-version }}
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: ${{ matrix.python-version }}
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install -r requirements.txt # test with requirements file so can easily bump with dependabot
24+
pip install pytest
25+
- name: Test
26+
run: |
27+
python -m pytest test_gui.py

.github/workflows/workflow-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ jobs:
2323
- name: Running test cases
2424
run: |
2525
pytest test.py
26+
- name: Running GUI tests
27+
run: |
28+
pytest test_gui.py

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ get-pip.py
99
run_app.bat
1010
python*
1111
**/__pycache__/
12-
gdpr_consent/node_modules/
12+
gdpr_consent/node_modules/
13+
*~

settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
"tag": "57690c44-d635-43b0-ab43-f8bd3064ca06"
1313
}
1414
},
15-
"online_deployment": false
15+
"online_deployment": false,
16+
"test": true
1617
}

src/common/common.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,17 @@ def page_setup(page: str = "") -> dict[str, Any]:
225225

226226
captcha_control()
227227

228+
# If run in hosted mode, show captcha as long as it has not been solved
229+
#if not "local" in sys.argv:
230+
# if "controllo" not in st.session_state:
231+
# # Apply captcha by calling the captcha_control function
232+
# captcha_control()
233+
234+
# If run in hosted mode, show captcha as long as it has not been solved
235+
if 'controllo' not in st.session_state or ("controllo" in params.keys() and params["controllo"] == False):
236+
# Apply captcha by calling the captcha_control function
237+
captcha_control()
238+
228239
return params
229240

230241

@@ -376,11 +387,16 @@ def get_current_chunk(df, chunk_size, chunk_index):
376387
)
377388

378389
rows = event["selection"]["rows"]
379-
if not rows:
390+
391+
if st.session_state.settings['test']: # is a test App, return first row as selected
392+
return 1
393+
elif not rows:
380394
return None
381-
# Calculate the index based on the current page and chunk size
382-
base_index = (page - 1) * chunk_size
383-
return base_index + rows[0]
395+
else:
396+
# Calculate the index based on the current page and chunk size
397+
base_index = (page - 1) * chunk_size
398+
print(base_index)
399+
return base_index + rows[0]
384400

385401

386402

test_gui.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from streamlit.testing.v1 import AppTest
2+
import pytest
3+
from src import fileupload
4+
import json
5+
from pathlib import Path
6+
import shutil
7+
8+
@pytest.fixture
9+
def launch(request):
10+
test = AppTest.from_file(request.param)
11+
12+
## Initialize session state ##
13+
with open("settings.json", "r") as f:
14+
test.session_state.settings = json.load(f)
15+
test.session_state.settings['test'] = True
16+
test.secrets['workspace'] = 'test'
17+
return test
18+
19+
20+
21+
# Test launching of all pages
22+
@pytest.mark.parametrize('launch', (
23+
#"content/quickstart.py", # NOTE: this page does not work due to streamlit.errors.StreamlitPageNotFoundError error
24+
"content/documentation.py",
25+
"content/topp_workflow_file_upload.py",
26+
"content/topp_workflow_parameter.py",
27+
"content/topp_workflow_execution.py",
28+
"content/topp_workflow_results.py",
29+
"content/file_upload.py",
30+
"content/raw_data_viewer.py",
31+
"content/run_example_workflow.py",
32+
"content/download_section.py",
33+
"content/simple_workflow.py",
34+
"content/run_subprocess.py"), indirect=True)
35+
def test_launch(launch):
36+
launch.run()
37+
assert not launch.exception
38+
39+
40+
41+
########### PAGE SPECIFIC TESTS ############
42+
@pytest.mark.parametrize('launch,selection', [("content/documentation.py", 'User Guide'),
43+
("content/documentation.py", 'Installation'),
44+
("content/documentation.py", 'Developers Guide: How to build app based on this template'),
45+
("content/documentation.py", 'Developers Guide: TOPP Workflow Framework'),
46+
("content/documentation.py", 'Developer Guide: Windows Executables'),
47+
("content/documentation.py", 'Developers Guide: Deployment')], indirect=['launch'])
48+
def test_documentation(launch, selection):
49+
launch.run()
50+
launch.selectbox[0].select(selection).run()
51+
assert not launch.exception
52+
53+
54+
@pytest.mark.parametrize('launch', ["content/file_upload.py"], indirect=True)
55+
def test_file_upload_load_example(launch):
56+
launch.run()
57+
for i in launch.tabs:
58+
if i.label == "Example Data":
59+
i.button[0].click().run()
60+
assert not launch.exception
61+
62+
63+
# NOTE: All tabs are automatically checked
64+
@pytest.mark.parametrize('launch,example', [("content/raw_data_viewer.py", 'Blank.mzML'),
65+
("content/raw_data_viewer.py", 'Treatment.mzML'),
66+
("content/raw_data_viewer.py", 'Pool.mzML'),
67+
("content/raw_data_viewer.py", 'Control.mzML')], indirect=['launch'])
68+
def test_view_raw_ms_data(launch, example):
69+
launch.run()
70+
71+
## Load Example file, based on implementation of fileupload.load_example_mzML_files() ###
72+
mzML_dir = Path(launch.session_state.workspace, "mzML-files")
73+
74+
# Copy files from example-data/mzML to workspace mzML directory, add to selected files
75+
for f in Path("example-data", "mzML").glob("*.mzML"):
76+
shutil.copy(f, mzML_dir)
77+
launch.run()
78+
79+
## TODO: Figure out a way to select a spectrum to be displayed
80+
launch.selectbox[0].select(example).run()
81+
assert not launch.exception
82+
83+
84+
@pytest.mark.parametrize('launch,example', [("content/run_example_workflow.py", ['Blank']),
85+
("content/run_example_workflow.py", ['Treatment']),
86+
("content/run_example_workflow.py", ['Pool']),
87+
("content/run_example_workflow.py", ['Control']),
88+
("content/run_example_workflow.py", ['Control', 'Blank'])], indirect=['launch'])
89+
def test_run_workflow(launch, example):
90+
launch.run()
91+
## Load Example file, based on implementation of fileupload.load_example_mzML_files() ###
92+
mzML_dir = Path(launch.session_state.workspace, "mzML-files")
93+
94+
# Copy files from example-data/mzML to workspace mzML directory, add to selected files
95+
for f in Path("example-data", "mzML").glob("*.mzML"):
96+
shutil.copy(f, mzML_dir)
97+
launch.run()
98+
99+
## Select experiments to process
100+
for e in example:
101+
launch.multiselect[0].select(e)
102+
103+
launch.run()
104+
assert not launch.exception
105+
106+
# Press the "Run Workflow" button
107+
launch.button[1].click().run(timeout=60)
108+
assert not launch.exception

0 commit comments

Comments
 (0)