Testing
Testing guidelines and structure for Copinance OS.
Test Structure
Tests are organized to mirror the source code structure:
tests/
├── unit/ # Unit tests
│ └── copinanceos/
│ ├── domain/
│ ├── application/
│ └── infrastructure/
└── integration/ # Integration tests
└── copinanceos/
└── infrastructure/Running Tests
# All tests
pytest
# Unit tests only
pytest -m unit
# Integration tests only
pytest -m integration
# With coverage
pytest --cov=copinanceos --cov-report=htmlWriting Tests
Unit Tests
Test individual components in isolation:
import pytest
from copinanceos.domain.models.job import Job, JobScope, JobStatus, JobTimeframe
def test_job_creation():
job = Job(
scope=JobScope.STOCK,
stock_symbol="AAPL",
timeframe=JobTimeframe.MID_TERM,
workflow_type="stock",
)
assert job.status == JobStatus.PENDINGIntegration Tests
Test component interactions:
import pytest
from copinanceos.infrastructure.repositories import StockRepositoryImpl
from copinanceos.domain.models.stock import Stock
@pytest.mark.integration
async def test_stock_repository_save_and_get(isolated_storage):
repo = StockRepositoryImpl(storage=isolated_storage)
stock = Stock(
symbol="AAPL",
name="Apple Inc.",
exchange="NASDAQ",
)
saved = await repo.save(stock)
retrieved = await repo.get_by_symbol(saved.symbol)
assert retrieved is not None
assert retrieved.symbol == saved.symbolTest Fixtures
Common fixtures are available in tests/conftest.py:
isolated_storage: Isolated storage for each testprofile_repository: Profile repository with isolated storage
Test Markers
Use markers to categorize tests:
@pytest.mark.unit
def test_unit_example():
pass
@pytest.mark.integration
async def test_integration_example():
passBest Practices
- Isolation: Each test should be independent
- Fixtures: Use fixtures for common setup
- Async: Use
pytest-asynciofor async tests - Coverage: Aim for high test coverage
- Naming: Use descriptive test names