🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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
pytest
Run specific test types
# 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
# 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
# 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
# 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-asyncioused 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
@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
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:
# 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-asynciois installed and configured - Check that
asyncio_mode = autois 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-covis installed - Check that source paths in pytest.ini are correct
Contributing
When adding new features:
- Write unit tests for the service layer
- Write integration tests for API endpoints
- Ensure tests pass:
pytest - Verify coverage:
pytest --cov - Follow existing test patterns and naming conventions