From 165db91b8d8a9a259e64ceefcae0f6845e5d6829 Mon Sep 17 00:00:00 2001 From: John McCardle Date: Wed, 21 Jan 2026 21:34:22 -0500 Subject: [PATCH] Organize test suite: add README, move loose tests to proper directories - Add tests/README.md documenting test structure and usage - Move issue_*_test.py files to tests/regression/ (9 files) - Move loose test_*.py files to tests/unit/ (18 files) - tests/ root now contains only pytest infrastructure Addresses #166 Co-Authored-By: Claude Opus 4.5 --- tests/README.md | 174 ++++++++++++++++++ .../issue_176_entity_position_test.py | 0 .../issue_177_gridpoint_grid_pos_test.py | 0 .../issue_179_181_grid_vectors_test.py | 0 .../issue_180_timer_orphan_test.py | 0 .../issue_180_timer_stopped_test.py | 0 .../issue_182_caption_size_test.py | 0 .../issue_184_189_module_test.py | 0 .../issue_185_188_bounds_test.py | 0 .../issue_190_layer_docs_test.py | 0 tests/{ => unit}/api_changes_batch_test.py | 0 tests/{ => unit}/minimal_reparent.py | 0 tests/{ => unit}/minimal_test.py | 0 tests/{ => unit}/test_append.py | 0 tests/{ => unit}/test_callback_vector.py | 0 tests/{ => unit}/test_caption_size.py | 0 tests/{ => unit}/test_children.py | 0 tests/{ => unit}/test_frame_bounds.py | 0 tests/{ => unit}/test_grid_features.py | 0 tests/{ => unit}/test_gridpoint_debug.py | 0 tests/{ => unit}/test_gridpoint_grid_pos.py | 0 tests/{ => unit}/test_iter_flush.py | 0 tests/{ => unit}/test_iter_only.py | 0 tests/{ => unit}/test_iteration.py | 0 tests/{ => unit}/test_layer_docs.py | 0 tests/{ => unit}/test_module_namespace.py | 0 tests/{ => unit}/test_module_simple.py | 0 tests/{ => unit}/test_scene_create.py | 0 28 files changed, 174 insertions(+) create mode 100644 tests/README.md rename tests/{ => regression}/issue_176_entity_position_test.py (100%) rename tests/{ => regression}/issue_177_gridpoint_grid_pos_test.py (100%) rename tests/{ => regression}/issue_179_181_grid_vectors_test.py (100%) rename tests/{ => regression}/issue_180_timer_orphan_test.py (100%) rename tests/{ => regression}/issue_180_timer_stopped_test.py (100%) rename tests/{ => regression}/issue_182_caption_size_test.py (100%) rename tests/{ => regression}/issue_184_189_module_test.py (100%) rename tests/{ => regression}/issue_185_188_bounds_test.py (100%) rename tests/{ => regression}/issue_190_layer_docs_test.py (100%) rename tests/{ => unit}/api_changes_batch_test.py (100%) rename tests/{ => unit}/minimal_reparent.py (100%) rename tests/{ => unit}/minimal_test.py (100%) rename tests/{ => unit}/test_append.py (100%) rename tests/{ => unit}/test_callback_vector.py (100%) rename tests/{ => unit}/test_caption_size.py (100%) rename tests/{ => unit}/test_children.py (100%) rename tests/{ => unit}/test_frame_bounds.py (100%) rename tests/{ => unit}/test_grid_features.py (100%) rename tests/{ => unit}/test_gridpoint_debug.py (100%) rename tests/{ => unit}/test_gridpoint_grid_pos.py (100%) rename tests/{ => unit}/test_iter_flush.py (100%) rename tests/{ => unit}/test_iter_only.py (100%) rename tests/{ => unit}/test_iteration.py (100%) rename tests/{ => unit}/test_layer_docs.py (100%) rename tests/{ => unit}/test_module_namespace.py (100%) rename tests/{ => unit}/test_module_simple.py (100%) rename tests/{ => unit}/test_scene_create.py (100%) diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..6ac2368 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,174 @@ +# McRogueFace Test Suite + +Automated tests for the McRogueFace game engine. + +## Directory Structure + +``` +tests/ +├── unit/ # Unit tests for individual components (155+ tests) +├── integration/ # Integration tests for system interactions +├── regression/ # Bug regression tests (issue_XX_*.py) +├── benchmarks/ # Performance benchmarks +├── demo/ # Interactive demo system +│ ├── demo_main.py # Demo runner +│ └── screens/ # Per-feature demo screens +├── conftest.py # Pytest configuration and fixtures +├── pytest.ini # Pytest settings +├── run_tests.py # Standalone test runner +└── KNOWN_ISSUES.md # Test status and mcrfpy.step() documentation +``` + +## Running Tests + +### With pytest (recommended) + +```bash +# Run all tests +pytest tests/ -v + +# Run specific directory +pytest tests/unit/ -v + +# Run tests matching a pattern +pytest tests/ -k "bsp" -v + +# Quick run with short timeout (some timeouts expected) +pytest tests/ -q --mcrf-timeout=5 + +# Full run with longer timeout +pytest tests/ -q --mcrf-timeout=30 + +# Stop on first failure +pytest tests/ -x +``` + +### With run_tests.py + +```bash +# Run all tests +python3 tests/run_tests.py + +# Run specific category +python3 tests/run_tests.py unit +python3 tests/run_tests.py regression + +# Verbose output +python3 tests/run_tests.py -v + +# Quiet (no checksums) +python3 tests/run_tests.py -q + +# Custom timeout +python3 tests/run_tests.py --timeout=30 +``` + +### Running individual tests + +```bash +cd build +./mcrogueface --headless --exec ../tests/unit/some_test.py +``` + +## Writing Tests + +### Test Pattern: Synchronous with `mcrfpy.step()` + +**Recommended:** Use `mcrfpy.step(t)` to advance simulation time synchronously. + +```python +import mcrfpy +import sys + +# Setup +scene = mcrfpy.Scene("test") +scene.activate() + +# Create UI elements +frame = mcrfpy.Frame(pos=(100, 100), size=(50, 50)) +scene.children.append(frame) + +# Start animation +frame.animate("x", 500.0, 1.0, mcrfpy.Easing.LINEAR) + +# Advance simulation synchronously +mcrfpy.step(1.5) + +# Verify results +if abs(frame.x - 500.0) < 0.1: + print("PASS") + sys.exit(0) +else: + print(f"FAIL: frame.x = {frame.x}, expected 500.0") + sys.exit(1) +``` + +### Test Pattern: Timer-based (legacy) + +For tests that need multiple timer callbacks or complex timing: + +```python +import mcrfpy +import sys + +def run_test(runtime): + # Test code here + print("PASS") + sys.exit(0) + +scene = mcrfpy.Scene("test") +scene.activate() + +# Timer fires after 100ms +timer = mcrfpy.Timer("test", run_test, 100) +# Script ends, game loop runs timer +``` + +### Test Output + +- Print `PASS` and `sys.exit(0)` for success +- Print `FAIL` with details and `sys.exit(1)` for failure +- Tests that timeout are marked as failures + +## Test Categories + +### Unit Tests (`unit/`) + +Test individual components in isolation: +- `*_test.py` - Standard component tests +- `api_*_test.py` - Python API tests +- `automation_*_test.py` - Automation module tests + +### Regression Tests (`regression/`) + +Tests for specific bug fixes, named by issue number: +- `issue_XX_description_test.py` + +### Integration Tests (`integration/`) + +Tests for system interactions and complex scenarios. + +### Benchmarks (`benchmarks/`) + +Performance measurement tests. + +### Demo (`demo/`) + +Interactive demonstrations of features. Run with: +```bash +cd build +./mcrogueface ../tests/demo/demo_main.py +``` + +## Tips + +- **Read tests as examples**: Tests show correct API usage +- **Use `mcrfpy.step()`**: Avoids timeout issues, makes tests deterministic +- **Check KNOWN_ISSUES.md**: Documents expected failures and workarounds +- **Screenshots**: Use `mcrfpy.automation.screenshot("name.png")` after `mcrfpy.step()` + +## See Also + +- `KNOWN_ISSUES.md` - Current test status and the `mcrfpy.step()` pattern +- `conftest.py` - Pytest fixtures and custom collector +- `demo/screens/` - Feature demonstrations (good API examples) diff --git a/tests/issue_176_entity_position_test.py b/tests/regression/issue_176_entity_position_test.py similarity index 100% rename from tests/issue_176_entity_position_test.py rename to tests/regression/issue_176_entity_position_test.py diff --git a/tests/issue_177_gridpoint_grid_pos_test.py b/tests/regression/issue_177_gridpoint_grid_pos_test.py similarity index 100% rename from tests/issue_177_gridpoint_grid_pos_test.py rename to tests/regression/issue_177_gridpoint_grid_pos_test.py diff --git a/tests/issue_179_181_grid_vectors_test.py b/tests/regression/issue_179_181_grid_vectors_test.py similarity index 100% rename from tests/issue_179_181_grid_vectors_test.py rename to tests/regression/issue_179_181_grid_vectors_test.py diff --git a/tests/issue_180_timer_orphan_test.py b/tests/regression/issue_180_timer_orphan_test.py similarity index 100% rename from tests/issue_180_timer_orphan_test.py rename to tests/regression/issue_180_timer_orphan_test.py diff --git a/tests/issue_180_timer_stopped_test.py b/tests/regression/issue_180_timer_stopped_test.py similarity index 100% rename from tests/issue_180_timer_stopped_test.py rename to tests/regression/issue_180_timer_stopped_test.py diff --git a/tests/issue_182_caption_size_test.py b/tests/regression/issue_182_caption_size_test.py similarity index 100% rename from tests/issue_182_caption_size_test.py rename to tests/regression/issue_182_caption_size_test.py diff --git a/tests/issue_184_189_module_test.py b/tests/regression/issue_184_189_module_test.py similarity index 100% rename from tests/issue_184_189_module_test.py rename to tests/regression/issue_184_189_module_test.py diff --git a/tests/issue_185_188_bounds_test.py b/tests/regression/issue_185_188_bounds_test.py similarity index 100% rename from tests/issue_185_188_bounds_test.py rename to tests/regression/issue_185_188_bounds_test.py diff --git a/tests/issue_190_layer_docs_test.py b/tests/regression/issue_190_layer_docs_test.py similarity index 100% rename from tests/issue_190_layer_docs_test.py rename to tests/regression/issue_190_layer_docs_test.py diff --git a/tests/api_changes_batch_test.py b/tests/unit/api_changes_batch_test.py similarity index 100% rename from tests/api_changes_batch_test.py rename to tests/unit/api_changes_batch_test.py diff --git a/tests/minimal_reparent.py b/tests/unit/minimal_reparent.py similarity index 100% rename from tests/minimal_reparent.py rename to tests/unit/minimal_reparent.py diff --git a/tests/minimal_test.py b/tests/unit/minimal_test.py similarity index 100% rename from tests/minimal_test.py rename to tests/unit/minimal_test.py diff --git a/tests/test_append.py b/tests/unit/test_append.py similarity index 100% rename from tests/test_append.py rename to tests/unit/test_append.py diff --git a/tests/test_callback_vector.py b/tests/unit/test_callback_vector.py similarity index 100% rename from tests/test_callback_vector.py rename to tests/unit/test_callback_vector.py diff --git a/tests/test_caption_size.py b/tests/unit/test_caption_size.py similarity index 100% rename from tests/test_caption_size.py rename to tests/unit/test_caption_size.py diff --git a/tests/test_children.py b/tests/unit/test_children.py similarity index 100% rename from tests/test_children.py rename to tests/unit/test_children.py diff --git a/tests/test_frame_bounds.py b/tests/unit/test_frame_bounds.py similarity index 100% rename from tests/test_frame_bounds.py rename to tests/unit/test_frame_bounds.py diff --git a/tests/test_grid_features.py b/tests/unit/test_grid_features.py similarity index 100% rename from tests/test_grid_features.py rename to tests/unit/test_grid_features.py diff --git a/tests/test_gridpoint_debug.py b/tests/unit/test_gridpoint_debug.py similarity index 100% rename from tests/test_gridpoint_debug.py rename to tests/unit/test_gridpoint_debug.py diff --git a/tests/test_gridpoint_grid_pos.py b/tests/unit/test_gridpoint_grid_pos.py similarity index 100% rename from tests/test_gridpoint_grid_pos.py rename to tests/unit/test_gridpoint_grid_pos.py diff --git a/tests/test_iter_flush.py b/tests/unit/test_iter_flush.py similarity index 100% rename from tests/test_iter_flush.py rename to tests/unit/test_iter_flush.py diff --git a/tests/test_iter_only.py b/tests/unit/test_iter_only.py similarity index 100% rename from tests/test_iter_only.py rename to tests/unit/test_iter_only.py diff --git a/tests/test_iteration.py b/tests/unit/test_iteration.py similarity index 100% rename from tests/test_iteration.py rename to tests/unit/test_iteration.py diff --git a/tests/test_layer_docs.py b/tests/unit/test_layer_docs.py similarity index 100% rename from tests/test_layer_docs.py rename to tests/unit/test_layer_docs.py diff --git a/tests/test_module_namespace.py b/tests/unit/test_module_namespace.py similarity index 100% rename from tests/test_module_namespace.py rename to tests/unit/test_module_namespace.py diff --git a/tests/test_module_simple.py b/tests/unit/test_module_simple.py similarity index 100% rename from tests/test_module_simple.py rename to tests/unit/test_module_simple.py diff --git a/tests/test_scene_create.py b/tests/unit/test_scene_create.py similarity index 100% rename from tests/test_scene_create.py rename to tests/unit/test_scene_create.py