lens-testing
GitHub指导如何为 Lens 变更编写后端 HTTP 契约测试,聚焦高风险场景如认证、路由及协议兼容性。通过 API fixtures 驱动端到端测试,严格区分实现细节与契约行为,确保测试风险导向且覆盖关键路径。
触发场景
安装
npx skills add dyedd/lens --skill lens-testing -g -y
SKILL.md
Frontmatter
{
"name": "lens-testing",
"description": "Use when a Lens change needs backend HTTP contract coverage. Keep tests risk-based, drive them through the API fixtures, and use the repository's uv-managed checks."
}
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 reproducible bug alone does not justify a test; the affected HTTP contract must warrant the coverage.
Do not automatically add frontend tests or direct tests of units, services, helpers, converters, or repositories. Follow explicit user instructions when they change the scope.
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 contract worth protecting.
- Reuse the nearest area file under
backend/tests/api/, plus fixtures and helpers inbackend/tests/conftest.py. - If coverage is justified, add the smallest request-and-response behavior test.
- Format touched files and run the smallest relevant check. For backend contract changes, run the API suite in parallel; narrow to one file only while debugging.
- Run frontend lint, type check, or build only when frontend files or the requested verification require them; CI remains the full repository check.
Conventions
One file per area, named backend/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 from the repository root, so it comes from the dev dependency group instead of a global install.
- Format and lint touched files:
uv run --no-sync ruff format <paths>thenuv run --no-sync ruff check --fix <paths> - Backend suite:
uv run --no-sync python -m pytest backend/tests/api -q --confcutdir=backend/tests -n auto --dist worksteal - One file, while debugging:
uv run --no-sync python -m pytest backend/tests/api/test_<area>_api.py -q --confcutdir=backend/tests - Frontend checks, from
frontend/:pnpm lint,pnpm exec tsc --noEmit, andpnpm build
pytest-xdist and ruff ship in the dev dependency group; install them with uv sync --locked. With a package index mirror configured, --locked misreports lockfile drift, so use uv sync --frozen.
Do not add another test runner or a custom parallel harness.
版本历史
-
3bd63f0
当前 2026-09-09 04:01
细化了触发测试的边界条件(从'可复现bug'改为'需权衡维护成本'),明确了 CI 中前端检查的触发时机,并更新了测试文件命名和断言规范。
- 2385417 2026-09-03 05:27
-
7461a01
2026-08-27 18:21
统一后端工具链至 uv,明确测试规范:补充测试写法约定,修正与并行运行冲突的旧描述,锁定依赖。
- 5563aba 2026-08-16 08:02


