Initial commit: scheduler service extraction from portainer-core
Build and Push / build (release) Failing after 17s
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>
This commit is contained in:
+202
@@ -0,0 +1,202 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user