一键导入
backend-testing
Pytest patterns for trader-pro modular backend. Load when writing, debugging, or analyzing backend test coverage
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Pytest patterns for trader-pro modular backend. Load when writing, debugging, or analyzing backend test coverage
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
External API evaluation and MCP server wrapper generation. Load when integrating a REST/GraphQL API as a workspace tool
Capability-based provider system patterns. Load when creating providers or wiring module-provider integration
Full-stack WebSocket subscription development. Load when adding WS routes, topic services, or debugging WS data flows
Systematic Python type error resolution (mypy/pyright). Load when fixing backend type check failures
Type-first Python with Pydantic, Protocol, and discriminated unions. Load when writing models or enforcing typing
Systematic type error resolution for Python (mypy/pyright) and TypeScript (vue-tsc). Use when fixing type errors, resolving type check failures, or optimizing type imports.
| name | backend-testing |
| description | Pytest patterns for trader-pro modular backend. Load when writing, debugging, or analyzing backend test coverage |
| user-invocable | false |
Pytest-specific testing methodology for the trader-pro modular backend. Covers fixture selection, test hierarchy, provider mocking, and project-specific conventions. Apply test-strategy skill first for general methodology, then this skill for pytest patterns.
| Tier | Location | Purpose | Command |
|---|---|---|---|
| Boundary | tests/ | Import isolation, registry, config | make test-boundaries |
| Unit (manager) | tests/unit/ | Backend manager logic | poetry run pytest tests/unit/ -v |
| Module unit | modules/<mod>/tests/ | Module endpoints & logic | make test-module-{name} |
| Integration | tests/integration/ | Multi-process, cross-module | make test-integration |
| Provider | providers/<name>/tests/ | Provider capabilities | make test-provider-{name} |
| Datastore | datastores/<impl>/tests/ | Implementation-specific | make test-datastores |
| Contract | tests/integration/test_datastore_contract.py | Interface compliance | (included in integration) |
Classify the test target → select the right fixture pattern:
| Target | Fixture | Scope |
|---|---|---|
| REST API endpoint | async_client: AsyncClient | function |
| WebSocket endpoint | client: TestClient | function |
| Module isolation | create_test_app(enabled_modules=[...]) | session |
| Production-like (build_modules) | Pattern 1 (full ModularApp) | session |
| Mock providers | Pattern 3 (provider injection) | function |
| TWS trackers | mock_ibsocket with MagicMock(spec=IbSocketWiringInterface) | function |
| PostgreSQL | test_settings → postgres_datastore | session |
test_settings — Settings SSOT (PostgreSQL auto-provisioned)apps — Full ModularApp with all modulesbroker_only_app / datafeed_only_app — Isolated module appsevent_loop — Required for session-scoped async fixturesasync_client — AsyncClient with raise_app_exceptions=Falseclient — TestClient with raise_server_exceptions=Falsetmp_path — Temporary directory (pytest built-in)from unittest.mock import MagicMock, PropertyMock
from trading_api.providers.tws.wiring_interfaces import IbSocketWiringInterface
@pytest.fixture
def mock_ibsocket():
mock = MagicMock(spec=IbSocketWiringInterface)
counter = {"value": 0}
def get_next_id():
counter["value"] += 1
return counter["value"]
type(mock).next_req_id = PropertyMock(side_effect=get_next_id)
mock.send_message = MagicMock()
return mock
@pytest.fixture
def mock_google_oauth(monkeypatch):
async def mock_parse_id_token(token, claims_options):
return {"sub": "test_user_id", "email": "test@example.com", "email_verified": True}
monkeypatch.setattr("authlib.integrations...", mock_parse_id_token)
Use parametrized any_datastore fixture to run against all implementations (InMemory + Postgres). Use reset() for test isolation. Protected by DATASTORE_ALLOW_RESET=True.
| Environment | Source | Detection |
|---|---|---|
| Local | testcontainers (auto) | DATASTORE_POSTGRES_DSN not set |
| CI | Service container | DATASTORE_POSTGRES_DSN set |
Both flow through test_settings session fixture in backend/conftest.py.
test_{behavior}_when_{condition}class Test{Feature}:monkeypatch over unittest.mock.patch when possible@pytest.mark.asyncio for all async testsraise_app_exceptions=False / raise_server_exceptions=False| Scope | Target |
|---|---|
| Unit test | < 100ms each |
| Module suite | < 5 seconds |
| Integration | < 1 minute |
| Full suite | < 2 minutes |
make -C backend test # All tests (incremental/testmon)
make -C backend test-full # All tests (complete, no testmon)
make -C backend test-modules # Module tests only
make -C backend test-module-broker # Specific module
make -C backend test-integration # Integration tests
make -C backend test-providers # All provider tests
make -C backend test-provider-tws # Specific provider
make -C backend test-datastores # Datastore tests
make -C backend test-boundaries # Boundary tests
make -C backend test-cov # With coverage report
Default make test uses pytest-testmon for incremental runs — only re-runs tests affected by changed files. This is fast but has blind spots.
| Changed | Testmon Misses | Explicit Supplement |
|---|---|---|
conftest.py fixtures | Tests using fixtures indirectly (via other fixtures) | make test-full for the affected scope |
| Provider callbacks / capabilities | Tests in modules consuming that provider | make test-module-{consumer} |
Pydantic models in models/ | Tests importing via re-exports or using serialized forms | make test-modules |
dev-config.yaml / settings | Tests relying on config values | make test-boundaries |
| Dynamic file scanning (boundaries) | Already handled — boundaries always runs explicitly | N/A (built into Makefile) |
| Datastore interface changes | Contract tests + implementation tests | make test-datastores |
After a testmon-incremental run, assess coverage gaps:
git diff --name-only HEAD~1 (or vs. branch)make -C backend test # Incremental (testmon) — fast, may miss gaps
make -C backend test-full # Complete suite — no gaps, slower
make -C backend testmon-forcerun # Rebuild testmon DB + run all
make -C backend testmon-reset # Clear testmon DB
make -C backend testmon-status # Check if DB exists
When to use test-full over test: After modifying fixtures, models shared across modules, config files, or provider interfaces.
__method()) — test public API insteadpoetry run pytest — use make targets for consistency