# Scheduler Tests Comprehensive test suite for The Scheduler using pytest. ## Test Structure ``` tests/ ├── conftest.py # Shared fixtures and configuration ├── test_api.py # API endpoint tests ├── test_example_executor.py # Example executor tests ├── test_doc_sync_executor.py # Documentation sync executor tests └── README.md # This file ``` ## Running Tests ### Run all tests ```bash docker exec scheduler pytest ``` ### Run with coverage report ```bash docker exec scheduler pytest --cov=src --cov-report=term-missing ``` ### Run specific test file ```bash docker exec scheduler pytest tests/test_api.py ``` ### Run specific test class ```bash docker exec scheduler pytest tests/test_api.py::TestHealthEndpoint ``` ### Run specific test ```bash docker exec scheduler pytest tests/test_api.py::TestHealthEndpoint::test_health_endpoint_returns_healthy ``` ### Run tests by marker ```bash # Run only unit tests docker exec scheduler pytest -m unit # Run only API tests docker exec scheduler pytest -m api # Run only executor tests docker exec scheduler pytest -m executor # Run only fast tests (exclude slow) docker exec scheduler pytest -m "not slow" ``` ### Run with verbose output ```bash docker exec scheduler pytest -v ``` ### Run with detailed failure output ```bash docker exec scheduler pytest -vv --tb=long ``` ### Stop on first failure ```bash docker exec scheduler pytest -x ``` ## Test Markers Tests are organized with pytest markers: - `@pytest.mark.unit` - Fast unit tests with no external dependencies - `@pytest.mark.integration` - Integration tests (may use database) - `@pytest.mark.api` - API endpoint tests - `@pytest.mark.executor` - Task executor tests - `@pytest.mark.slow` - Tests that take a while to run ## Coverage Reports After running tests with coverage: - **Terminal**: Shows missing lines in terminal output - **HTML**: Open `htmlcov/index.html` in browser for detailed report - **JSON**: Machine-readable coverage data in `coverage.json` View HTML coverage report: ```bash # From host machine open /home/jpmschweitzer/docker-data/scheduler/htmlcov/index.html ``` ## Writing New Tests ### Test File Naming - Test files must start with `test_` - Place in `tests/` directory - Use descriptive names: `test_.py` ### Test Function Naming - Test functions must start with `test_` - Use descriptive names: `test_` ### Using Fixtures Fixtures are defined in `conftest.py`: ```python def test_something(test_settings, auth_headers): # Use fixtures as function parameters assert test_settings.app_name == "Test Scheduler" ``` ### Adding Markers ```python @pytest.mark.unit @pytest.mark.api def test_health_endpoint(client): response = client.get("/health") assert response.status_code == 200 ``` ### Async Tests ```python @pytest.mark.asyncio async def test_async_function(): result = await some_async_function() assert result is not None ``` ### Mocking ```python from unittest.mock import patch, MagicMock def test_with_mock(): with patch('module.function') as mock_func: mock_func.return_value = "mocked" result = call_function_that_uses_it() assert result == "mocked" ``` ## Continuous Integration These tests are designed to run in CI pipelines: ```yaml # Example GitHub Actions - name: Run tests run: | docker exec scheduler pytest --cov=src --cov-report=xml docker exec scheduler pytest --cov=src --cov-report=html ``` ## Test Database Tests use mocked database connections by default. For integration tests that require a real database: 1. Set up a test database 2. Use `POSTGRES_DB=test_scheduler` environment variable 3. Run migrations before tests 4. Clean up after tests ## Troubleshooting ### Tests fail with "ModuleNotFoundError" ```bash # Install test dependencies docker exec scheduler /venv/bin/pip install -r requirements.txt ``` ### Tests fail with database errors - Tests use mocked connections by default - Check that mocks are properly set up in conftest.py - For integration tests, ensure test database exists ### Coverage not working ```bash # Reinstall pytest-cov docker exec scheduler /venv/bin/pip install --upgrade pytest-cov ``` ## Best Practices 1. **Fast by default**: Unit tests should be fast (<1s each) 2. **Isolated**: Tests should not depend on each other 3. **Descriptive**: Test names should clearly describe what they test 4. **Single assertion**: Test one thing per test when possible 5. **Use fixtures**: Reuse common setup via fixtures 6. **Mock external deps**: Don't hit real databases/APIs in unit tests 7. **Mark appropriately**: Use markers to categorize tests ## Current Coverage Run this to see current coverage: ```bash docker exec scheduler pytest --cov=src --cov-report=term ``` Target: 80%+ code coverage for critical paths