Kaynağa Gözat

docs: add testing guide README

Includes:
- Quick start commands
- Test structure overview
- Unit vs integration test instructions
- Coverage report generation
- CI behavior explanation
- Examples for adding new tests
- Troubleshooting section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 1 hafta önce
ebeveyn
işleme
cdb06b4dfc
1 değiştirilmiş dosya ile 190 ekleme ve 0 silme
  1. 190 0
      tests/README.md

+ 190 - 0
tests/README.md

@@ -0,0 +1,190 @@
+# Testing Guide
+
+This document explains how to run tests for the Dune Weaver backend.
+
+## Quick Start
+
+```bash
+# Install test dependencies
+pip install -r requirements-dev.txt
+
+# Run all unit tests (no hardware needed)
+pytest tests/unit/ -v
+
+# Run with coverage report
+pytest tests/ --cov=modules --cov-report=term-missing
+```
+
+## Test Structure
+
+```
+tests/
+├── conftest.py              # Shared fixtures
+├── unit/                    # Unit tests (run in CI, no hardware)
+│   ├── conftest.py
+│   ├── test_api_patterns.py
+│   ├── test_api_playlists.py
+│   ├── test_api_status.py
+│   ├── test_connection_manager.py
+│   ├── test_pattern_manager.py
+│   └── test_playlist_manager.py
+├── integration/             # Integration tests (require hardware)
+│   ├── conftest.py
+│   ├── test_hardware.py
+│   ├── test_playback_controls.py
+│   └── test_playlist.py
+└── fixtures/                # Test data files
+```
+
+## Unit Tests
+
+Unit tests mock all hardware dependencies and run quickly. They're safe to run anywhere.
+
+```bash
+# Run all unit tests
+pytest tests/unit/ -v
+
+# Run specific test file
+pytest tests/unit/test_pattern_manager.py -v
+
+# Run specific test
+pytest tests/unit/test_api_status.py::test_get_status -v
+
+# Run tests matching a pattern
+pytest tests/unit/ -v -k "playlist"
+```
+
+## Integration Tests
+
+Integration tests require the sand table hardware to be connected. They are **skipped by default**.
+
+```bash
+# Run integration tests (with hardware connected)
+pytest tests/integration/ --run-hardware -v
+
+# Run specific integration test file
+pytest tests/integration/test_playback_controls.py --run-hardware -v
+
+# Run with output visible (helpful for debugging)
+pytest tests/integration/ --run-hardware -v -s
+```
+
+### Integration Test Categories
+
+| File | What it tests | Duration |
+|------|---------------|----------|
+| `test_hardware.py` | Serial connection, homing, movement, pattern execution | ~5-10 min |
+| `test_playback_controls.py` | Pause, resume, stop, skip, speed control | ~5 min |
+| `test_playlist.py` | Playlist modes, clear patterns, state updates | ~5 min |
+
+### Safety Notes
+
+- **Movement tests physically move the table** — ensure the ball path is clear
+- **Homing tests run the homing sequence** — table will move to home position
+- **Pattern tests execute real patterns** — star.thr runs end-to-end
+
+## Coverage Reports
+
+```bash
+# Terminal report
+pytest tests/ --cov=modules --cov-report=term-missing
+
+# HTML report (creates htmlcov/ directory)
+pytest tests/ --cov=modules --cov-report=html
+open htmlcov/index.html
+
+# XML report (for CI tools)
+pytest tests/ --cov=modules --cov-report=xml
+```
+
+## CI Behavior
+
+When `CI=true` environment variable is set:
+- All `@pytest.mark.hardware` tests are automatically skipped
+- Unit tests run normally
+
+```bash
+# Simulate CI environment locally
+CI=true pytest tests/ -v
+```
+
+## Common Commands
+
+| Command | Description |
+|---------|-------------|
+| `pytest tests/unit/ -v` | Run unit tests |
+| `pytest tests/integration/ --run-hardware -v` | Run integration tests |
+| `pytest tests/ --cov=modules` | Run with coverage |
+| `pytest tests/ -v -k "pattern"` | Run tests matching "pattern" |
+| `pytest tests/ -x` | Stop on first failure |
+| `pytest tests/ --lf` | Run only last failed tests |
+| `pytest tests/ -v -s` | Show print statements |
+
+## Adding New Tests
+
+### Unit Test Example
+
+```python
+# tests/unit/test_my_feature.py
+import pytest
+from unittest.mock import MagicMock, patch
+
+def test_my_function():
+    """Test description here."""
+    # Arrange
+    expected = "result"
+
+    # Act
+    result = my_function()
+
+    # Assert
+    assert result == expected
+
+@pytest.mark.asyncio
+async def test_async_function(async_client):
+    """Test async endpoint."""
+    response = await async_client.get("/my_endpoint")
+    assert response.status_code == 200
+```
+
+### Integration Test Example
+
+```python
+# tests/integration/test_my_hardware.py
+import pytest
+
+@pytest.mark.hardware
+@pytest.mark.slow
+def test_hardware_operation(hardware_port, run_hardware):
+    """Test that requires real hardware."""
+    if not run_hardware:
+        pytest.skip("Hardware tests disabled")
+
+    from modules.connection import connection_manager
+
+    conn = connection_manager.SerialConnection(hardware_port)
+    try:
+        assert conn.is_connected()
+        # ... test hardware operation
+    finally:
+        conn.close()
+```
+
+## Troubleshooting
+
+### Tests hang or timeout
+- Check if hardware is connected and powered on
+- Verify serial port is not in use by another application
+- Try running with `-s` flag to see output
+
+### Import errors
+- Ensure you're in the project root directory
+- Install dependencies: `pip install -r requirements-dev.txt`
+
+### Hardware tests skip unexpectedly
+- Make sure to pass `--run-hardware` flag
+- Check that `CI` environment variable is not set
+
+### Coverage shows 0%
+- Ensure `relative_files = true` is in pyproject.toml
+- Run from project root directory