Files
pi-pm3/tests
michael 4f35df1781 Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:46:22 -08:00
..
2026-01-06 13:46:22 -08:00
2026-01-06 13:46:22 -08:00
2026-01-06 13:46:22 -08:00
2026-01-06 13:46:22 -08:00
2026-01-06 13:46:22 -08:00

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-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

@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-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