- Refactored REST API server to use non-blocking background task - Fixed setpoint manager bug in get_all_current_setpoints() method - Added proper authentication to REST API test - All 6 optimization-to-SCADA integration tests now passing - All 5 safety workflow tests continue to pass Key changes: 1. REST API server now starts in background task using asyncio.create_task() 2. Added proper server state management (_is_running, _server_task, _server) 3. Implemented proper shutdown mechanism with task cancellation 4. Fixed dictionary iteration bug in setpoint manager 5. Updated test to use correct admin password (admin123) 6. Test now authenticates before accessing protected endpoints |
||
|---|---|---|
| .. | ||
| integration | ||
| unit | ||
| README.md | ||
| conftest.py | ||
| test_safety.py | ||
README.md
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
# 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
# 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 withTest*, methods starting withtest_* - 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 testsmock_pump_data: Mock pump datamock_safety_limits: Mock safety limitsmock_station_data: Mock station datamock_pump_plan: Mock pump planmock_feedback_data: Mock feedback data
Writing Tests
Unit Test Guidelines
- Isolation: Mock external dependencies
- Speed: Tests should run quickly
- Readability: Clear test names and assertions
- Coverage: Test both success and failure cases
Example:
@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
- Markers: Use
@pytest.mark.integrationand@pytest.mark.database - Setup: Use fixtures for test data setup
- Cleanup: Ensure proper cleanup after tests
- Realistic: Test with realistic data and scenarios
Example:
@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
- Unit Tests: Run on every commit
- Integration Tests: Run on main branch and PRs
- Coverage: Enforce minimum 80% coverage
- 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_<module_name>.py - Classes:
Test<ClassName> - Methods:
test_<scenario>_<expected_behavior>
Assertions
- Use descriptive assertion messages
- Test both positive and negative cases
- Verify side effects when appropriate
Async Testing
- Use
@pytest.mark.asynciofor async tests - Use
pytest_asyncio.fixturefor async fixtures - Handle async context managers properly
Mocking
- Mock external dependencies
- Use
unittest.mock.patchfor module-level mocking - Verify mock interactions when necessary
Troubleshooting
Common Issues
- Database Connection: Ensure test database is running
- Async Tests: Use proper async fixtures and markers
- Import Errors: Check PYTHONPATH and module structure
- Mock Issues: Verify mock setup and teardown
Debugging
- Use
pytest -vfor verbose output - Use
pytest --pdbto 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
--coverageflag - Minimum: 80% coverage enforced
Run pytest --cov=src --cov-report=html and open htmlcov/index.html in a browser.