Instruction file imported from azusa152/Folio (
.cursor/rules/testing.mdc). Copyright stays with the author.
Backend Testing Standards (pytest)
Every feature MUST ship with tests. Bug fixes MUST include regression tests. No untested code in production.
Test File Structure
Tests live in backend/tests/ mirroring the source layout. Sub-packages mirror their source counterparts — e.g., tests/domain/analysis/ for domain/analysis/, tests/application/stock/ for application/stock/, tests/api/routes/ for api/routes/, tests/infrastructure/market_data/ for infrastructure/market_data/.
Test Naming
Use descriptive names: test_<function>_should_<expected_behavior>
AAA Pattern
Every test follows Arrange / Act / Assert. See backend/tests/ for canonical examples.
Fixtures & conftest.py
conftest.pyprovides:TestClient, in-memory SQLite DB, mock yfinance data, mock Telegram sender.- Use
@pytest.fixturewith appropriate scope (sessionfor DB,functionfor per-test isolation).
Mock External Services
- yfinance, Telegram Bot API, and any network I/O MUST be mocked. Never hit real APIs in tests.
- Use
unittest.mock.patchorpytest-mockto replace infrastructure adapters. - Patch at the actual module, not a re-export shim. Private symbols (e.g.,
_fetch_signals_from_yf) must be patched at their definition site:infrastructure.market_data.market_data._fetch_signals_from_yf, notinfrastructure.market_data._fetch_signals_from_yf.
Minimum Test Coverage Per Endpoint
| Scenario | Status Code |
|---|---|
| Happy path | 200 / 201 |
| Validation error | 422 |
| Not found | 404 |
| Conflict / duplicate | 409 (where applicable) |
Webhook Action Coverage
- Every webhook action MUST have at least one happy-path test and one error-path test.
- The
helpaction must be tested to ensure discoverability stays accurate.
Architecture Boundary Tests
Architecture boundary tests in backend/tests/test_architecture.py enforce layer dependency rules using Python's AST module:
- Domain must not import from
application,infrastructure, orapi. - Infrastructure must not import from
applicationorapi. - API routes (
api/routes/) may only import frominfrastructure.database(forget_session); all otherinfrastructure.*imports are forbidden — includinginfrastructure.persistence.*,infrastructure.market_data.*, andinfrastructure.external.*.
Any new module must not violate the allowed import directions. Run make test to verify boundaries have not regressed.