# TESTING.md — WalletPress

> Test strategy. Unit, integration, e2e, fixtures.

## Test Pyramid

```
       /\
      /  \      E2E (slow, few)
     /----\
    /      \    Integration (medium, more)
   /--------\
  /          \  Unit (fast, many)
 /____________\
```

- **Unit tests**: test individual functions/classes in isolation
- **Integration tests**: test components together (DB, API, auth)
- **E2E tests**: test full user flows (slow, run before deploy)

## Structure
```
tests/
├── unit/          # fast, no external deps
├── integration/   # uses test DB, mocks external APIs
├── e2e/           # full stack, runs against staging
├── fixtures/      # test data (mainnet guard: no real addresses/keys)
└── conftest.py    # pytest config
```

## Running

```bash
make test                  # all tests
make test-unit            # only unit
make test-integration     # only integration
make test-cov             # with coverage report
pytest tests/unit/test_X.py -v   # single file
```

## Fixtures

Use pytest fixtures. Examples:
- `clean_db` — fresh DB per test
- `mock_helius` — mock Helius API responses
- `auth_headers` — Bearer token for test user
- `sample_token` — fake token (test address, NOT mainnet)

**NEVER use mainnet data in tests.** Pre-commit hook blocks this.

## Coverage
- Target: >80% on changed lines
- Enforced in CI via `--cov-fail-under=80`

## Mocking
- `httpx` for HTTP mocking (use `respx` or `pytest-httpx`)
- `unittest.mock` for general mocking
- VCR.py for recording/replaying API calls

## Performance Tests
- `locust` for load testing (run against staging)
- Profile with `py-spy` or `cProfile`

## CI
Every PR runs:
1. Lint (ruff)
2. Type check (mypy strict)
3. Unit tests + coverage
4. Integration tests (test DB)
5. Security scan (bandit, gitleaks)
6. Build Docker image (verify it compiles)

Merge blocked if any fails.
