🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
231 lines
6.0 KiB
Markdown
231 lines
6.0 KiB
Markdown
# Dangerous Pi Test Suite
|
|
|
|
Comprehensive test suite for the Dangerous Pi backend refactoring.
|
|
|
|
## Test Structure
|
|
|
|
```
|
|
tests/
|
|
├── conftest.py # Shared fixtures and configuration
|
|
├── unit/ # Unit tests (isolated, fast)
|
|
│ └── services/ # Service layer tests
|
|
│ ├── test_pm3_service.py
|
|
│ ├── test_system_service.py
|
|
│ ├── test_wifi_service.py
|
|
│ └── test_update_service.py
|
|
└── integration/ # Integration tests (API + services)
|
|
└── api/ # API endpoint tests
|
|
├── test_pm3_api.py
|
|
└── ...
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
### Run all tests
|
|
```bash
|
|
pytest
|
|
```
|
|
|
|
### Run specific test types
|
|
```bash
|
|
# Unit tests only
|
|
pytest tests/unit/
|
|
|
|
# Integration tests only
|
|
pytest tests/integration/
|
|
|
|
# Specific service tests
|
|
pytest tests/unit/services/test_pm3_service.py
|
|
```
|
|
|
|
### Run with coverage
|
|
```bash
|
|
# Generate coverage report
|
|
pytest --cov=app/backend/services --cov=app/backend/api --cov-report=html
|
|
|
|
# View coverage report
|
|
open htmlcov/index.html
|
|
```
|
|
|
|
### Run specific test classes or methods
|
|
```bash
|
|
# Run specific test class
|
|
pytest tests/unit/services/test_pm3_service.py::TestPM3ServiceCommandExecution
|
|
|
|
# Run specific test method
|
|
pytest tests/unit/services/test_pm3_service.py::TestPM3ServiceCommandExecution::test_execute_command_success
|
|
```
|
|
|
|
### Run with markers
|
|
```bash
|
|
# Run only async tests
|
|
pytest -m asyncio
|
|
|
|
# Run only unit tests
|
|
pytest -m unit
|
|
|
|
# Skip slow tests
|
|
pytest -m "not slow"
|
|
```
|
|
|
|
## Test Coverage
|
|
|
|
The test suite covers:
|
|
|
|
### Unit Tests (tests/unit/services/)
|
|
|
|
**PM3Service** (test_pm3_service.py):
|
|
- ✅ Command execution with session validation
|
|
- ✅ Session locked error handling
|
|
- ✅ PM3 not connected error handling
|
|
- ✅ Command failure handling
|
|
- ✅ Exception handling
|
|
- ✅ Status queries
|
|
- ✅ Connection management
|
|
- ✅ Session management (create, release, get info)
|
|
|
|
**SystemService** (test_system_service.py):
|
|
- ✅ System information queries (CPU, memory, disk)
|
|
- ✅ CPU temperature reading
|
|
- ✅ Shutdown operations (immediate and delayed)
|
|
- ✅ Restart operations (immediate and delayed)
|
|
- ✅ Shutdown cancellation
|
|
- ✅ Log retrieval
|
|
- ✅ Service status queries
|
|
- ✅ Error handling for all operations
|
|
|
|
**WiFiService** (test_wifi_service.py):
|
|
- ✅ WiFi status queries (AP and client modes)
|
|
- ✅ Network scanning
|
|
- ✅ Network connection (encrypted and open)
|
|
- ✅ Network disconnection
|
|
- ✅ Mode switching (AP, client, dual, auto, off)
|
|
- ✅ Invalid mode handling
|
|
- ✅ Dual mode without USB adapter error
|
|
- ✅ Saved network management
|
|
- ✅ Forget network operation
|
|
|
|
**UpdateService** (test_update_service.py):
|
|
- ✅ Update checking (available and up-to-date)
|
|
- ✅ Update downloading
|
|
- ✅ Update installation
|
|
- ✅ Progress monitoring (all states)
|
|
- ✅ Release notes retrieval
|
|
- ✅ Combined operations (check+download, full update)
|
|
- ✅ Error handling for no update available/downloaded
|
|
|
|
### Integration Tests (tests/integration/api/)
|
|
|
|
**PM3 API** (test_pm3_api.py):
|
|
- ✅ Status endpoint integration with PM3Service
|
|
- ✅ Command endpoint with session management
|
|
- ✅ HTTP status code mapping (423 for session locked, 503 for not connected)
|
|
- ✅ Connection/disconnection endpoints
|
|
- ✅ Request/response format consistency
|
|
|
|
## Best Practices Demonstrated
|
|
|
|
### 1. Proper Test Isolation
|
|
- Each test is independent and can run in any order
|
|
- Mocks are used to isolate unit tests from external dependencies
|
|
- Fixtures provide clean test setup
|
|
|
|
### 2. Clear Test Structure
|
|
- Tests follow Arrange-Act-Assert (AAA) pattern
|
|
- Descriptive test names explain what is being tested
|
|
- Test classes group related tests logically
|
|
|
|
### 3. Comprehensive Coverage
|
|
- Both success and error paths tested
|
|
- Edge cases covered (session locked, not connected, etc.)
|
|
- Exception handling verified
|
|
|
|
### 4. Async Test Support
|
|
- `pytest-asyncio` used for testing async code
|
|
- Proper mocking of async functions with `AsyncMock`
|
|
|
|
### 5. Integration Testing
|
|
- API endpoints tested with FastAPI TestClient
|
|
- Service integration verified
|
|
- HTTP status codes validated
|
|
|
|
### 6. Maintainability
|
|
- Shared fixtures in conftest.py reduce duplication
|
|
- Clear documentation in test docstrings
|
|
- Consistent naming conventions
|
|
|
|
## Writing New Tests
|
|
|
|
### Unit Test Template
|
|
```python
|
|
@pytest.mark.asyncio
|
|
async def test_feature_success(self, mock_dependency):
|
|
"""Test description."""
|
|
# Arrange
|
|
mock_dependency.method.return_value = expected_value
|
|
service = YourService(mock_dependency)
|
|
|
|
# Act
|
|
result = await service.your_method()
|
|
|
|
# Assert
|
|
assert result.success is True
|
|
assert result.data["key"] == expected_value
|
|
mock_dependency.method.assert_called_once()
|
|
```
|
|
|
|
### Integration Test Template
|
|
```python
|
|
def test_api_endpoint_success(self, test_client, mock_service):
|
|
"""Test API endpoint description."""
|
|
# Arrange
|
|
mock_service.method.return_value = ServiceResult(...)
|
|
|
|
# Act
|
|
with patch('app.backend.api.module.container.service', mock_service):
|
|
response = test_client.post("/api/endpoint", json={...})
|
|
|
|
# Assert
|
|
assert response.status_code == 200
|
|
assert response.json()["key"] == expected_value
|
|
```
|
|
|
|
## CI/CD Integration
|
|
|
|
Tests can be run in CI/CD pipelines:
|
|
|
|
```yaml
|
|
# Example GitHub Actions
|
|
- name: Run tests
|
|
run: |
|
|
pytest --cov --cov-report=xml
|
|
|
|
- name: Upload coverage
|
|
uses: codecov/codecov-action@v3
|
|
with:
|
|
file: ./coverage.xml
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Tests fail with "RuntimeError: Event loop is closed"
|
|
- Ensure `pytest-asyncio` is installed and configured
|
|
- Check that `asyncio_mode = auto` is set in pytest.ini
|
|
|
|
### Import errors
|
|
- Verify that PYTHONPATH includes project root
|
|
- Check that all __init__.py files are present
|
|
|
|
### Coverage not generated
|
|
- Ensure `pytest-cov` is installed
|
|
- Check that source paths in pytest.ini are correct
|
|
|
|
## Contributing
|
|
|
|
When adding new features:
|
|
1. Write unit tests for the service layer
|
|
2. Write integration tests for API endpoints
|
|
3. Ensure tests pass: `pytest`
|
|
4. Verify coverage: `pytest --cov`
|
|
5. Follow existing test patterns and naming conventions
|