Build and Push / build (release) Failing after 17s
Extracted standalone scheduler service with: - FastAPI REST API for task management - APScheduler-based task execution - PostgreSQL persistence - Docker container support - Gitea Actions CI/CD workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
203 lines
4.8 KiB
Markdown
203 lines
4.8 KiB
Markdown
# 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_<module_name>.py`
|
|
|
|
### Test Function Naming
|
|
- Test functions must start with `test_`
|
|
- Use descriptive names: `test_<what_is_being_tested>`
|
|
|
|
### 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
|