Skip to content

Commit 055fb45

Browse files
committed
Test viz in CI
1 parent d4b18cd commit 055fb45

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

.github/workflows/test_viz.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Test viz
2+
3+
on:
4+
push:
5+
paths:
6+
- 'examples/**/app.py' # If an example visualisation is modified
7+
- 'examples/**/viz.py' # If an example visualisation is modified
8+
- 'viz.py' # If the test script is modified
9+
- '.github/workflows/test_viz.yml' # If this workflow is modified
10+
pull_request:
11+
paths:
12+
- 'examples/**/*.py'
13+
- 'test_examples.py'
14+
- '.github/workflows/test_examples.yml'
15+
workflow_dispatch:
16+
schedule:
17+
- cron: '0 6 * * 1' # Monday at 6:00 UTC
18+
19+
jobs:
20+
# build-stable:
21+
# runs-on: ubuntu-latest
22+
# steps:
23+
# - uses: actions/checkout@v4
24+
# - name: Set up Python
25+
# uses: actions/setup-python@v5
26+
# with:
27+
# python-version: "3.12"
28+
# - name: Install dependencies
29+
# run: pip install mesa pytest
30+
# - name: Test with pytest
31+
# run: pytest -rA -Werror test_examples.py
32+
33+
build-pre:
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v4
37+
- name: Set up Python
38+
uses: actions/setup-python@v5
39+
with:
40+
python-version: "3.12"
41+
- name: Install dependencies
42+
run: |
43+
pip install --pre mesa[viz]
44+
pip install .[test]
45+
- name: Test with pytest
46+
run: pytest -rA -Werror -Wdefault::FutureWarning viz.py
47+
48+
# build-main:
49+
# runs-on: ubuntu-latest
50+
# steps:
51+
# - uses: actions/checkout@v4
52+
# - name: Set up Python
53+
# uses: actions/setup-python@v5
54+
# with:
55+
# python-version: "3.12"
56+
# - name: Install dependencies
57+
# run: |
58+
# pip install .[test]
59+
# pip install -U git+https://github.com/projectmesa/mesa@main#egg=mesa
60+
# - name: Test with pytest
61+
# run: pytest -rA -Werror -Wdefault::FutureWarning test_examples.py

viz.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import importlib
2+
import os
3+
import sys
4+
import time
5+
6+
import pytest
7+
from mesa.visualization import SolaraViz
8+
9+
10+
def get_viz_files(directory):
11+
viz_files = []
12+
for root, dirs, files in os.walk(directory):
13+
for file in files:
14+
if file in ["app.py", "viz.py"]:
15+
module_name = os.path.relpath(os.path.join(root, file[:-3])).replace(
16+
os.sep, "."
17+
)
18+
viz_files.append(module_name)
19+
return viz_files
20+
21+
22+
@pytest.mark.parametrize("module_name", get_viz_files("examples"))
23+
def test_solara_viz(module_name):
24+
# Add the 'examples' directory to the Python path
25+
examples_dir = os.path.abspath(
26+
os.path.join(os.path.dirname(__file__), "..", "examples")
27+
)
28+
sys.path.insert(0, examples_dir)
29+
30+
# Add the parent directory of the module to the Python path
31+
module_parent_dir = os.path.abspath(
32+
os.path.join(examples_dir, os.path.dirname(module_name.replace(".", os.sep)))
33+
)
34+
if module_parent_dir not in sys.path:
35+
sys.path.insert(0, module_parent_dir)
36+
37+
# Import the visualization module
38+
module = importlib.import_module(module_name)
39+
40+
# Find the SolaraViz instance
41+
solara_viz = None
42+
for item_name in dir(module):
43+
item = getattr(module, item_name)
44+
if isinstance(item, SolaraViz):
45+
solara_viz = item
46+
break
47+
48+
assert solara_viz is not None, f"No SolaraViz instance found in {module_name}"
49+
50+
# Get the model instance
51+
model = solara_viz.model
52+
53+
# Store the initial state
54+
initial_step = model.steps
55+
56+
# Do 3 steps
57+
for _ in range(3):
58+
model.step()
59+
assert model.steps == initial_step + 3
60+
61+
# Pause (no actual pause needed in this context)
62+
63+
# 3 more steps
64+
for _ in range(3):
65+
model.step()
66+
assert model.steps == initial_step + 6
67+
68+
# Reset
69+
model_params = solara_viz.model_params
70+
new_model = model.__class__(**model_params)
71+
solara_viz.model = new_model
72+
model = new_model
73+
74+
assert model.steps == 0 or model.steps == initial_step
75+
76+
# Run steps for 5 seconds
77+
start_time = time.time()
78+
while time.time() - start_time < 5:
79+
model.step()
80+
81+
# Pause (no actual pause needed in this context)
82+
83+
# Check if the step counter has increased
84+
assert model.steps > 0, "Model did not advance steps"
85+
86+
print(f"Test completed for {module_name}. Final step count: {model.steps}")
87+
88+
# Remove the added directories from the Python path
89+
sys.path.pop(0)
90+
if module_parent_dir in sys.path:
91+
sys.path.remove(module_parent_dir)
92+
93+
94+
# Run the tests
95+
if __name__ == "__main__":
96+
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)