Skip to content

Commit 8d960a7

Browse files
Refactor testing framework with pytest fixtures and modular architecture
1 parent 10df0a1 commit 8d960a7

10 files changed

Lines changed: 1116 additions & 239 deletions

File tree

tests/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,103 @@ Example output structure:
237237
"parameters": {...}
238238
}
239239
}
240+
```
241+
242+
---
243+
244+
# Testing Framework
245+
246+
## Project Structure
247+
248+
```
249+
tests/
250+
├── feature_test_cli.py # Main CLI tool
251+
├── conftest.py # Pytest fixtures & helpers
252+
├── test_helpers/ # Reusable utilities
253+
│ ├── cli_formatting.py # Colors & formatting
254+
│ ├── thresholds.py # Threshold values
255+
│ └── base_tester.py # Base tester class
256+
└── unit/
257+
└── test_complete.py # Unit tests (50 tests)
258+
```
259+
260+
## Running Tests
261+
262+
```bash
263+
# Run all tests
264+
python -m pytest tests/unit/test_complete.py -v
265+
266+
# Run quietly
267+
python -m pytest tests/unit/test_complete.py -q
268+
269+
# Run specific test class
270+
python -m pytest tests/unit/test_complete.py::TestSynchronizationTester -v
271+
272+
# Run specific test
273+
python -m pytest tests/unit/test_complete.py::TestSynchronizationTester::test_basic_sync_test -v
274+
```
275+
276+
## Writing Tests
277+
278+
We will be using fixtures from `conftest.py` instead of creating test files manually:
279+
280+
```python
281+
def test_example(sync_tester):
282+
"""Test synchronization."""
283+
result = sync_tester.test('sine', length=100, freq=1.0)
284+
assert_valid_result(result, ['plv', 'phase_status'])
285+
assert result['plv'] > 0.5
286+
```
287+
288+
Available fixtures:
289+
- `sync_tester` - SynchronizationTester
290+
- `smoothness_tester` - SmoothnessTester
291+
- `symmetry_tester` - BilateralSymmetryTester
292+
- `equilibrium_tester` - EquilibriumTester
293+
- `contraction_tester` - ContractionExpansionTester
294+
295+
Helper function `assert_valid_result(result, expected_keys)` validates results contain expected keys.
296+
297+
## Parametrized Tests
298+
299+
Test multiple scenarios efficiently:
300+
301+
```python
302+
@pytest.mark.parametrize("signal_type", ['sine', 'square', 'triangle'])
303+
def test_multiple_signals(sync_tester, signal_type):
304+
result = sync_tester.test(signal_type, length=100)
305+
assert_valid_result(result, ['plv'])
306+
```
307+
308+
## Thresholds
309+
310+
Threshold values are in `test_helpers/thresholds.py`:
311+
312+
```python
313+
from tests.test_helpers import FeatureThresholds
314+
315+
thresholds = FeatureThresholds()
316+
thresholds.sync.HIGH # 0.8
317+
thresholds.smoothness.VERY_SMOOTH # -1.6
318+
thresholds.equilibrium.HIGH_STABILITY # 0.9
319+
thresholds.symmetry.HIGH_SYMMETRY # 0.95
320+
```
321+
322+
Edit that file to change threshold values globally.
323+
324+
## Troubleshooting
325+
326+
**Import errors**: Install package in editable mode
327+
```bash
328+
pip install -e .
329+
```
330+
331+
**Fixtures not found**: Verify conftest.py location
332+
```bash
333+
python -m pytest tests/ --collect-only
334+
```
335+
336+
**Slow tests**: Use quiet mode
337+
```bash
338+
python -m pytest tests/unit/test_complete.py -q --tb=line
240339
```

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""PyEyesWeb Testing Framework."""

tests/conftest.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""Pytest configuration and shared fixtures for tests."""
2+
import pytest
3+
from tests.feature_test_cli import (
4+
SynchronizationTester,
5+
SmoothnessTester,
6+
BilateralSymmetryTester,
7+
EquilibriumTester,
8+
ContractionExpansionTester
9+
)
10+
11+
12+
# ============================================================================
13+
# FIXTURES FOR FEATURE TESTERS
14+
# ============================================================================
15+
16+
@pytest.fixture
17+
def sync_tester():
18+
"""Fixture for SynchronizationTester with verbose=False."""
19+
return SynchronizationTester(verbose=False)
20+
21+
22+
@pytest.fixture
23+
def smoothness_tester():
24+
"""Fixture for SmoothnessTester with verbose=False."""
25+
return SmoothnessTester(verbose=False)
26+
27+
28+
@pytest.fixture
29+
def symmetry_tester():
30+
"""Fixture for BilateralSymmetryTester with verbose=False."""
31+
return BilateralSymmetryTester(verbose=False)
32+
33+
34+
@pytest.fixture
35+
def equilibrium_tester():
36+
"""Fixture for EquilibriumTester with verbose=False."""
37+
return EquilibriumTester(verbose=False)
38+
39+
40+
@pytest.fixture
41+
def contraction_tester():
42+
"""Fixture for ContractionExpansionTester with verbose=False."""
43+
return ContractionExpansionTester(verbose=False)
44+
45+
46+
# ============================================================================
47+
# HELPER FUNCTIONS
48+
# ============================================================================
49+
50+
def assert_valid_result(result, expected_keys):
51+
"""
52+
Assert that a test result is valid and contains expected keys.
53+
54+
Args:
55+
result: The result dictionary to validate
56+
expected_keys: List of keys that should be present
57+
"""
58+
assert result is not None, "Result should not be None"
59+
for key in expected_keys:
60+
assert key in result, f"Result should contain key '{key}'"

0 commit comments

Comments
 (0)