lens-testing
GitHub规范 Lens 后端 HTTP API 关键契约测试的编写与运行,聚焦认证、持久化等高风险场景,禁止前端及单元测试,通过并行执行保障质量。
Trigger Scenarios
Install
npx skills add dyedd/lens --skill lens-testing -g -y
SKILL.md
Frontmatter
{
"name": "lens-testing",
"description": "Apply Lens's scope policy and writing conventions for critical backend HTTP API tests, and run the backend suite in parallel through the uv-managed toolchain. Validate the frontend with static checks instead of frontend tests."
}
Lens Testing
Scope
Cover only critical, high-risk backend HTTP contracts: authentication and authorization, data persistence or loss, gateway protocol compatibility, and routing or failover behavior. A new route or a reproducible bug does not by itself justify a test; add one only when the affected HTTP contract warrants the maintenance cost.
Never add frontend tests, nor direct tests of units, services, helpers, converters, repositories, or other implementation details.
Delete a test once the behavior it guarded is covered elsewhere, or once the field or option it pinned has been removed or derived.
Workflow
- Trace the affected HTTP path and decide whether it is a high-risk contract.
- Reuse the nearest area file under
tests/api/, and the fixtures and helpers intests/conftest.py. - If coverage is justified, add the smallest request-and-response behavior test.
- Format the touched files, then run the backend suite in parallel; narrow to one file only to debug a single failure.
- Let CI repeat the backend suite and run the frontend lint, type check, and build.
Conventions
One file per area, named tests/api/test_<area>_api.py. Name each test after the behavior it asserts, and separate arrange, act, and assert with blank lines.
- Drive every test through the
clientfixture. A test that bypasses HTTP, by calling a service function directly or by hand-building aRequest, is testing an implementation detail. - Build state through the admin API with the shared fixtures
admin_headers,create_site,create_model_group,create_gateway_key, andcreate_site_group_and_key. Import helpers withfrom conftest import ...:valid_site_payload,gateway_headers,openai_chat_channel_id,seed_request_log,assert_error, andjson_response. - Stub only at the network edge, by monkeypatching
proxy_upstream._send_upstreamor by injecting anhttpx.MockTransportclient, so the gateway path under test still runs end to end. Never monkeypatch the function under test and then assert on its own return value. - Assert one invariant per test, and express variants with
pytest.mark.parametrizeandpytest.param(..., id=...)rather than copied test bodies. For schema rejection cases, parametrize a mutator that edits an otherwise valid payload. - Assert only what the HTTP contract promises. Response item order is not a contract unless the endpoint documents it; compare sorted values or sets instead.
- For protocol and streaming coverage, keep the upstream frames literal in the test, then assert both the converted client-visible body and the persisted request log.
- Do not restate what the framework already guarantees. Request and backup models inherit
StrictBaseModel(extra="forbid"), so one representative case per schema family covers rejected extra fields and missing required fields; do not add a case per field. - Do not write per-endpoint 401 tests.
test_every_admin_route_rejects_missing_tokenwalksapp.routesand covers the whole admin surface; when a new admin route is intentionally public, add it to_UNAUTHENTICATED_ADMIN_ROUTESin the same change.
Commands
Call every backend tool through uv run --no-sync, so it comes from the dev extra instead of a global install.
- Format touched files:
uv run --no-sync black <paths> - Backend suite:
uv run --no-sync python -m pytest tests/api -q --confcutdir=tests -n auto --dist worksteal - One file, while debugging:
uv run --no-sync python -m pytest tests/api/test_<area>_api.py -q --confcutdir=tests - Frontend checks:
pnpm lint,pnpm exec tsc --noEmit, andpnpm build
pytest-xdist and black ship in the dev extra; install them with uv sync --extra dev --locked. With a package index mirror configured, --locked misreports lockfile drift, so use uv sync --extra dev --frozen and do not run uv lock, which would rewrite every URL in uv.lock to the mirror.
Do not add another test runner or a custom parallel harness.
Version History
-
7461a01
Current 2026-08-27 18:21
统一后端工具链至 uv,明确测试规范:补充测试写法约定,修正与并行运行冲突的旧描述,锁定依赖。
- 5563aba 2026-08-16 08:02


