# Calejo Control Adapter Test Suite This directory contains comprehensive tests for the Calejo Control Adapter system, following idiomatic Python testing practices. ## Test Organization ### Directory Structure ``` tests/ ├── unit/ # Unit tests (fast, isolated) │ ├── test_database_client.py │ ├── test_auto_discovery.py │ ├── test_safety_framework.py │ └── test_configuration.py ├── integration/ # Integration tests (require external services) │ └── test_phase1_integration.py ├── fixtures/ # Test data and fixtures ├── conftest.py # Pytest configuration and shared fixtures ├── test_phase1.py # Legacy Phase 1 test script ├── test_safety.py # Legacy safety tests └── README.md # This file ``` ### Test Categories - **Unit Tests**: Fast tests that don't require external dependencies - **Integration Tests**: Tests that require database or other external services - **Database Tests**: Tests marked with `@pytest.mark.database` - **Safety Tests**: Tests for safety framework components ## Running Tests ### Using the Test Runner ```bash # Run all tests ./run_tests.py # Run unit tests only ./run_tests.py --type unit # Run integration tests only ./run_tests.py --type integration # Run with coverage ./run_tests.py --coverage # Run quick tests (unit tests without database) ./run_tests.py --quick # Run tests with specific markers ./run_tests.py --marker safety --marker database # Verbose output ./run_tests.py --verbose ``` ### Using Pytest Directly ```bash # Run all tests pytest # Run unit tests pytest tests/unit/ # Run integration tests pytest tests/integration/ # Run tests with specific markers pytest -m "safety and database" # Run tests excluding specific markers pytest -m "not database" # Run with coverage pytest --cov=src --cov-report=html ``` ## Test Configuration ### Pytest Configuration Configuration is in `pytest.ini` at the project root: - **Test Discovery**: Files matching `test_*.py`, classes starting with `Test*`, methods starting with `test_*` - **Markers**: Predefined markers for different test types - **Coverage**: Minimum 80% coverage required - **Async Support**: Auto-mode for async tests ### Test Fixtures Shared fixtures are defined in `tests/conftest.py`: - `test_db_client`: Database client for integration tests - `mock_pump_data`: Mock pump data - `mock_safety_limits`: Mock safety limits - `mock_station_data`: Mock station data - `mock_pump_plan`: Mock pump plan - `mock_feedback_data`: Mock feedback data ## Writing Tests ### Unit Test Guidelines 1. **Isolation**: Mock external dependencies 2. **Speed**: Tests should run quickly 3. **Readability**: Clear test names and assertions 4. **Coverage**: Test both success and failure cases Example: ```python @pytest.mark.asyncio async def test_database_connection_success(self, db_client): """Test successful database connection.""" with patch('psycopg2.pool.ThreadedConnectionPool') as mock_pool: mock_pool_instance = Mock() mock_pool.return_value = mock_pool_instance await db_client.connect() assert db_client.connection_pool is not None mock_pool.assert_called_once() ``` ### Integration Test Guidelines 1. **Markers**: Use `@pytest.mark.integration` and `@pytest.mark.database` 2. **Setup**: Use fixtures for test data setup 3. **Cleanup**: Ensure proper cleanup after tests 4. **Realistic**: Test with realistic data and scenarios Example: ```python @pytest.mark.integration @pytest.mark.database class TestPhase1Integration: @pytest.mark.asyncio async def test_database_connection_integration(self, integration_db_client): """Test database connection and basic operations.""" assert integration_db_client.health_check() is True ``` ## Test Data ### Mock Data Mock data is provided through fixtures for consistent testing: - **Pump Data**: Complete pump configuration - **Safety Limits**: Safety constraints and limits - **Station Data**: Pump station metadata - **Pump Plans**: Optimization plans from Calejo Optimize - **Feedback Data**: Real-time pump feedback ### Database Test Data Integration tests use the test database with predefined data: - Multiple pump stations with different configurations - Various pump types and control methods - Safety limits for different scenarios - Historical pump plans and feedback ## Continuous Integration ### Test Execution in CI 1. **Unit Tests**: Run on every commit 2. **Integration Tests**: Run on main branch and PRs 3. **Coverage**: Enforce minimum 80% coverage 4. **Safety Tests**: Required for safety-critical components ### Environment Setup Integration tests require: - PostgreSQL database with test schema - Test database user with appropriate permissions - Environment variables for database connection ## Best Practices ### Test Naming - **Files**: `test_.py` - **Classes**: `Test` - **Methods**: `test__` ### Assertions - Use descriptive assertion messages - Test both positive and negative cases - Verify side effects when appropriate ### Async Testing - Use `@pytest.mark.asyncio` for async tests - Use `pytest_asyncio.fixture` for async fixtures - Handle async context managers properly ### Mocking - Mock external dependencies - Use `unittest.mock.patch` for module-level mocking - Verify mock interactions when necessary ## Troubleshooting ### Common Issues 1. **Database Connection**: Ensure test database is running 2. **Async Tests**: Use proper async fixtures and markers 3. **Import Errors**: Check PYTHONPATH and module structure 4. **Mock Issues**: Verify mock setup and teardown ### Debugging - Use `pytest -v` for verbose output - Use `pytest --pdb` to drop into debugger on failure - Check test logs for additional information ## Coverage Reports Coverage reports are generated in HTML format: - **Location**: `htmlcov/index.html` - **Requirements**: Run with `--coverage` flag - **Minimum**: 80% coverage enforced Run `pytest --cov=src --cov-report=html` and open `htmlcov/index.html` in a browser.