@tinkcarlos/skillora 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/.temp-skill-index.md +245 -0
- package/.claude/skills/SKILL.md +264 -0
- package/.claude/skills/api-scaffolding/SKILL.md +431 -0
- package/.claude/skills/api-scaffolding/agents/backend-architect.md +282 -0
- package/.claude/skills/api-scaffolding/agents/django-pro.md +144 -0
- package/.claude/skills/api-scaffolding/agents/fastapi-pro.md +156 -0
- package/.claude/skills/api-scaffolding/agents/graphql-architect.md +146 -0
- package/.claude/skills/api-scaffolding/skills/fastapi-templates/SKILL.md +171 -0
- package/.claude/skills/api-testing-observability/SKILL.md +583 -0
- package/.claude/skills/api-testing-observability/agents/api-documenter.md +146 -0
- package/.claude/skills/api-testing-observability/commands/api-mock.md +1320 -0
- package/.claude/skills/brainstorming/SKILL.md +283 -0
- package/.claude/skills/bug-fixing/SKILL.md +382 -0
- package/.claude/skills/bug-fixing/references/backend-guide.md +132 -0
- package/.claude/skills/bug-fixing/references/bug-guide.md +354 -0
- package/.claude/skills/bug-fixing/references/bug-record-template.md +134 -0
- package/.claude/skills/bug-fixing/references/bug-records.md +88 -0
- package/.claude/skills/bug-fixing/references/code-review-gate.md +81 -0
- package/.claude/skills/bug-fixing/references/common-bugs.md +140 -0
- package/.claude/skills/bug-fixing/references/complete-workflow.md +361 -0
- package/.claude/skills/bug-fixing/references/config-driven-fixes.md +136 -0
- package/.claude/skills/bug-fixing/references/context-isolation-protocol.md +268 -0
- package/.claude/skills/bug-fixing/references/cross-surface-regression.md +120 -0
- package/.claude/skills/bug-fixing/references/database-investigation.md +129 -0
- package/.claude/skills/bug-fixing/references/dependency-and-integrity-protocol.md +369 -0
- package/.claude/skills/bug-fixing/references/fix-completeness-checklist.md +239 -0
- package/.claude/skills/bug-fixing/references/frontend-guide.md +219 -0
- package/.claude/skills/bug-fixing/references/fullstack-joint-guide.md +123 -0
- package/.claude/skills/bug-fixing/references/functional-breakage.md +117 -0
- package/.claude/skills/bug-fixing/references/ide-lint-errors-guide.md +176 -0
- package/.claude/skills/bug-fixing/references/impact-analysis.md +511 -0
- package/.claude/skills/bug-fixing/references/investigation-checklist.md +263 -0
- package/.claude/skills/bug-fixing/references/knowledge-extraction-guide.md +531 -0
- package/.claude/skills/bug-fixing/references/knowledge-workflow.md +212 -0
- package/.claude/skills/bug-fixing/references/post-edit-quality-gate.md +30 -0
- package/.claude/skills/bug-fixing/references/python-env-and-testing.md +126 -0
- package/.claude/skills/bug-fixing/references/rca-guide.md +428 -0
- package/.claude/skills/bug-fixing/references/similar-bug-patterns.md +113 -0
- package/.claude/skills/bug-fixing/references/skill-delegation-guide.md +350 -0
- package/.claude/skills/bug-fixing/references/skill-orchestration.md +155 -0
- package/.claude/skills/bug-fixing/references/testing-strategy.md +350 -0
- package/.claude/skills/bug-fixing/references/tooling-build-scripts.md +162 -0
- package/.claude/skills/bug-fixing/references/user-input-validation.md +77 -0
- package/.claude/skills/bug-fixing/references/ux-patterns.md +158 -0
- package/.claude/skills/bug-fixing/references/windows-terminal-hygiene.md +106 -0
- package/.claude/skills/bug-fixing/references/zero-regression-matrix.md +239 -0
- package/.claude/skills/bug-fixing/references/zero-risk-protocol.md +102 -0
- package/.claude/skills/bug-fixing/scripts/format_code.py +611 -0
- package/.claude/skills/bug-fixing/scripts/generate_report_template.py +74 -0
- package/.claude/skills/bug-fixing/scripts/lint_check.py +816 -0
- package/.claude/skills/bug-fixing/scripts/requirements.txt +36 -0
- package/.claude/skills/cicd-pipeline/SKILL.md +300 -0
- package/.claude/skills/code-review/SKILL.md +535 -0
- package/.claude/skills/code-review/references/anti-pattern-scan.md +102 -0
- package/.claude/skills/code-review/references/automated-analysis.md +456 -0
- package/.claude/skills/code-review/references/backend-common-issues.md +589 -0
- package/.claude/skills/code-review/references/backend-expert-guide.md +415 -0
- package/.claude/skills/code-review/references/backend-review.md +868 -0
- package/.claude/skills/code-review/references/batch-processing-strategy.md +198 -0
- package/.claude/skills/code-review/references/call-chain-analysis-protocol.md +166 -0
- package/.claude/skills/code-review/references/common-patterns.md +321 -0
- package/.claude/skills/code-review/references/configuration-review.md +425 -0
- package/.claude/skills/code-review/references/control-flow-completeness.md +114 -0
- package/.claude/skills/code-review/references/database-review.md +298 -0
- package/.claude/skills/code-review/references/dependency-and-integrity-protocol.md +313 -0
- package/.claude/skills/code-review/references/external-standards.md +51 -0
- package/.claude/skills/code-review/references/feature-review.md +329 -0
- package/.claude/skills/code-review/references/file-review-template.md +326 -0
- package/.claude/skills/code-review/references/frontend-advanced.md +654 -0
- package/.claude/skills/code-review/references/frontend-common-issues.md +482 -0
- package/.claude/skills/code-review/references/frontend-expert-guide.md +342 -0
- package/.claude/skills/code-review/references/frontend-review.md +783 -0
- package/.claude/skills/code-review/references/fullstack-consistency.md +418 -0
- package/.claude/skills/code-review/references/fullstack-review.md +477 -0
- package/.claude/skills/code-review/references/functional-completeness.md +386 -0
- package/.claude/skills/code-review/references/hidden-bugs-detection.md +473 -0
- package/.claude/skills/code-review/references/ide-lint-errors-guide.md +173 -0
- package/.claude/skills/code-review/references/infrastructure-review.md +453 -0
- package/.claude/skills/code-review/references/iteration-review.md +264 -0
- package/.claude/skills/code-review/references/job-review.md +335 -0
- package/.claude/skills/code-review/references/layered-checklist-protocol.md +157 -0
- package/.claude/skills/code-review/references/logic-completeness.md +535 -0
- package/.claude/skills/code-review/references/mandatory-checklist.md +288 -0
- package/.claude/skills/code-review/references/multi-language-guide.md +800 -0
- package/.claude/skills/code-review/references/new-project-review.md +226 -0
- package/.claude/skills/code-review/references/non-code-files-review.md +451 -0
- package/.claude/skills/code-review/references/overlooked-issues.md +657 -0
- package/.claude/skills/code-review/references/platform-specific-review.md +195 -0
- package/.claude/skills/code-review/references/precision-analysis-protocol.md +260 -0
- package/.claude/skills/code-review/references/python-patterns.md +494 -0
- package/.claude/skills/code-review/references/rca-techniques.md +362 -0
- package/.claude/skills/code-review/references/report-template.md +430 -0
- package/.claude/skills/code-review/references/resource-limits-and-degradation.md +137 -0
- package/.claude/skills/code-review/references/review-dimensions.md +311 -0
- package/.claude/skills/code-review/references/review-guide.md +202 -0
- package/.claude/skills/code-review/references/review-knowledge-workflow.md +257 -0
- package/.claude/skills/code-review/references/review-progress-tracker-protocol.md +172 -0
- package/.claude/skills/code-review/references/review-record-template.md +195 -0
- package/.claude/skills/code-review/references/skill-orchestration.md +143 -0
- package/.claude/skills/code-review/references/ui-ux-review.md +470 -0
- package/.claude/skills/containerization/SKILL.md +313 -0
- package/.claude/skills/database-migrations/agents/database-admin.md +142 -0
- package/.claude/skills/database-migrations/agents/database-optimizer.md +144 -0
- package/.claude/skills/database-migrations/commands/migration-observability.md +408 -0
- package/.claude/skills/database-migrations/commands/sql-migrations.md +492 -0
- package/.claude/skills/finishing-a-development-branch/SKILL.md +319 -0
- package/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/.claude/skills/frontend-design/SKILL.md +587 -0
- package/.claude/skills/frontend-design/references/color-consistency.md +487 -0
- package/.claude/skills/frontend-design/references/color-palettes-full.md +657 -0
- package/.claude/skills/frontend-design/references/design-system-generator.md +285 -0
- package/.claude/skills/frontend-design/references/font-pairings-full.md +705 -0
- package/.claude/skills/frontend-design/references/industry-anti-patterns.md +281 -0
- package/.claude/skills/frontend-design/references/layout-anti-patterns.md +582 -0
- package/.claude/skills/frontend-design/references/motion-patterns.md +659 -0
- package/.claude/skills/frontend-design/references/pre-delivery-checklist.md +153 -0
- package/.claude/skills/frontend-design/references/responsive-design.md +555 -0
- package/.claude/skills/frontend-design/references/style-modification-rules.md +335 -0
- package/.claude/skills/frontend-design/references/ui-styles-full.md +383 -0
- package/.claude/skills/frontend-design/references/ui-styles-rating.md +191 -0
- package/.claude/skills/frontend-design/references/ux-guidelines.md +640 -0
- package/.claude/skills/fullstack-developer/SKILL.md +512 -0
- package/.claude/skills/fullstack-developer/references/api-contract-guide.md +312 -0
- package/.claude/skills/fullstack-developer/references/api-response-patterns.md +223 -0
- package/.claude/skills/fullstack-developer/references/async-patterns.md +220 -0
- package/.claude/skills/fullstack-developer/references/bug-prevention.md +914 -0
- package/.claude/skills/fullstack-developer/references/code-quality-checklist.md +271 -0
- package/.claude/skills/fullstack-developer/references/complete-development-workflow.md +278 -0
- package/.claude/skills/fullstack-developer/references/context-isolation-protocol.md +256 -0
- package/.claude/skills/fullstack-developer/references/database-migration.md +331 -0
- package/.claude/skills/fullstack-developer/references/dependency-and-integrity-protocol.md +390 -0
- package/.claude/skills/fullstack-developer/references/development-phases.md +333 -0
- package/.claude/skills/fullstack-developer/references/expert-guide.md +214 -0
- package/.claude/skills/fullstack-developer/references/file-import-patterns.md +114 -0
- package/.claude/skills/fullstack-developer/references/graceful-degradation-patterns.md +78 -0
- package/.claude/skills/fullstack-developer/references/ide-lint-errors-guide.md +183 -0
- package/.claude/skills/fullstack-developer/references/integration-testing.md +301 -0
- package/.claude/skills/fullstack-developer/references/mock-api-patterns.md +307 -0
- package/.claude/skills/fullstack-developer/references/phase-gate-template.md +249 -0
- package/.claude/skills/fullstack-developer/references/post-edit-quality-gate.md +30 -0
- package/.claude/skills/fullstack-developer/references/python-engineering.md +79 -0
- package/.claude/skills/fullstack-developer/references/skill-orchestration.md +214 -0
- package/.claude/skills/fullstack-developer/references/skill-router-table.md +304 -0
- package/.claude/skills/fullstack-developer/references/state-sync.md +217 -0
- package/.claude/skills/fullstack-developer/references/ui-testing-checklist.md +292 -0
- package/.claude/skills/fullstack-developer/scripts/format_code.py +611 -0
- package/.claude/skills/fullstack-developer/scripts/lint_check.py +816 -0
- package/.claude/skills/fullstack-developer/scripts/requirements.txt +36 -0
- package/.claude/skills/performance-optimization/SKILL.md +250 -0
- package/.claude/skills/product-requirements/SKILL.md +357 -0
- package/.claude/skills/product-requirements/references/acceptance-criteria.md +335 -0
- package/.claude/skills/product-requirements/references/answer-first-questioning-protocol.md +299 -0
- package/.claude/skills/product-requirements/references/competitive-analysis-guide.md +183 -0
- package/.claude/skills/product-requirements/references/document-accuracy-protocol.md +253 -0
- package/.claude/skills/product-requirements/references/document-management-protocol.md +278 -0
- package/.claude/skills/product-requirements/references/external-standards.md +62 -0
- package/.claude/skills/product-requirements/references/feature-spec-template.md +359 -0
- package/.claude/skills/product-requirements/references/knowledge-acquisition-protocol.md +251 -0
- package/.claude/skills/product-requirements/references/plan-execution-protocol.md +334 -0
- package/.claude/skills/product-requirements/references/plan-generation-protocol.md +264 -0
- package/.claude/skills/product-requirements/references/prioritization-frameworks.md +80 -0
- package/.claude/skills/product-requirements/references/requirement-decomposition-protocol.md +291 -0
- package/.claude/skills/product-requirements/references/user-story-examples.md +297 -0
- package/.claude/skills/product-requirements/references/workflow-templates.md +266 -0
- package/.claude/skills/react-best-practices/SKILL.md +198 -0
- package/.claude/skills/react-best-practices/references/advanced-patterns.md +94 -0
- package/.claude/skills/react-best-practices/references/bundle-optimization.md +182 -0
- package/.claude/skills/react-best-practices/references/client-data-fetching.md +112 -0
- package/.claude/skills/react-best-practices/references/complete-guide.md +2249 -0
- package/.claude/skills/react-best-practices/references/eliminating-waterfalls.md +169 -0
- package/.claude/skills/react-best-practices/references/javascript-performance.md +256 -0
- package/.claude/skills/react-best-practices/references/rendering-performance.md +230 -0
- package/.claude/skills/react-best-practices/references/rerender-optimization.md +214 -0
- package/.claude/skills/react-best-practices/references/server-performance.md +182 -0
- package/.claude/skills/security-audit/SKILL.md +226 -0
- package/.claude/skills/shared-references/advanced-debugging-techniques.md +186 -0
- package/.claude/skills/shared-references/code-quality-checklist.md +218 -0
- package/.claude/skills/shared-references/code-review-efficiency-guide.md +125 -0
- package/.claude/skills/shared-references/mcp-dependency-compatibility-protocol.md +276 -0
- package/.claude/skills/shared-references/skill-call-graph.md +230 -0
- package/.claude/skills/shared-references/skill-orchestration-protocol.md +281 -0
- package/.claude/skills/shared-references/subagent-dispatch-templates.md +199 -0
- package/.claude/skills/skill-expert-skills/LICENSE.txt +204 -0
- package/.claude/skills/skill-expert-skills/QUICK_NAVIGATION.md +374 -0
- package/.claude/skills/skill-expert-skills/SKILL.md +247 -0
- package/.claude/skills/skill-expert-skills/docs/_index.md +91 -0
- package/.claude/skills/skill-expert-skills/references/deep-research-methodology.md +389 -0
- package/.claude/skills/skill-expert-skills/references/docs-generation-workflow.md +398 -0
- package/.claude/skills/skill-expert-skills/references/domain-expertise-protocol.md +343 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/_index.md +54 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/backend-expertise.md +517 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/bug-fixing-expertise.md +363 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/code-review-expertise.md +392 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/frontend-expertise.md +410 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge-template.md +503 -0
- package/.claude/skills/skill-expert-skills/references/examples.md +782 -0
- package/.claude/skills/skill-expert-skills/references/integration-examples.md +655 -0
- package/.claude/skills/skill-expert-skills/references/knowledge-validation-checklist.md +246 -0
- package/.claude/skills/skill-expert-skills/references/latest-knowledge-acquisition.md +461 -0
- package/.claude/skills/skill-expert-skills/references/mcp-tools-guide.md +439 -0
- package/.claude/skills/skill-expert-skills/references/official-best-practices.md +616 -0
- package/.claude/skills/skill-expert-skills/references/patterns.md +218 -0
- package/.claude/skills/skill-expert-skills/references/plugin-skills-guide.md +432 -0
- package/.claude/skills/skill-expert-skills/references/requirement-elicitation-protocol.md +290 -0
- package/.claude/skills/skill-expert-skills/references/skill-creator-SKILL.md +353 -0
- package/.claude/skills/skill-expert-skills/references/skill-templates.md +583 -0
- package/.claude/skills/skill-expert-skills/references/skills-knowledge-base.md +561 -0
- package/.claude/skills/skill-expert-skills/references/tools-guide.md +379 -0
- package/.claude/skills/skill-expert-skills/references/troubleshooting.md +378 -0
- package/.claude/skills/skill-expert-skills/references/universality-guide.md +205 -0
- package/.claude/skills/skill-expert-skills/references/writing-style-guide.md +466 -0
- package/.claude/skills/skill-expert-skills/scripts/__pycache__/quick_validate.cpython-313.pyc +0 -0
- package/.claude/skills/skill-expert-skills/scripts/__pycache__/universal_validate.cpython-313.pyc +0 -0
- package/.claude/skills/skill-expert-skills/scripts/analyze_trigger.py +425 -0
- package/.claude/skills/skill-expert-skills/scripts/diff_with_official.py +188 -0
- package/.claude/skills/skill-expert-skills/scripts/init_skill.py +349 -0
- package/.claude/skills/skill-expert-skills/scripts/package_skill.py +156 -0
- package/.claude/skills/skill-expert-skills/scripts/quick_validate.py +493 -0
- package/.claude/skills/skill-expert-skills/scripts/requirements.txt +2 -0
- package/.claude/skills/skill-expert-skills/scripts/universal_validate.py +182 -0
- package/.claude/skills/skill-expert-skills/scripts/upgrade_skill.py +431 -0
- package/.claude/skills/subagent-driven-development/SKILL.md +268 -0
- package/.claude/skills/test-driven-development/SKILL.md +246 -0
- package/.claude/skills/test-driven-development/references/testing-anti-patterns.md +192 -0
- package/.claude/skills/using-git-worktrees/SKILL.md +266 -0
- package/.claude/skills/using-skillstack/SKILL.md +127 -0
- package/.claude/skills/vercel-deploy/SKILL.md +166 -0
- package/.claude/skills/vercel-deploy/scripts/deploy.sh +249 -0
- package/.claude/skills/verification-before-completion/SKILL.md +305 -0
- package/.claude/skills/writing-plans/SKILL.md +259 -0
- package/README.md +69 -0
- package/bin/cli.js +468 -0
- package/lib/init.js +333 -0
- package/package.json +29 -0
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-testing-observability
|
|
3
|
+
description: |
|
|
4
|
+
API testing and observability with contract validation, monitoring, and log analysis.
|
|
5
|
+
|
|
6
|
+
Use when:
|
|
7
|
+
- Testing API endpoints (unit/integration/contract)
|
|
8
|
+
- Setting up API monitoring and observability
|
|
9
|
+
- Creating mock servers for development
|
|
10
|
+
- Validating API contracts
|
|
11
|
+
- Setting up structured logging and log aggregation
|
|
12
|
+
- Implementing error tracking (Sentry)
|
|
13
|
+
|
|
14
|
+
Key Features:
|
|
15
|
+
- Contract testing: OpenAPI validation
|
|
16
|
+
- Mock server: Realistic API simulation
|
|
17
|
+
- Observability: Logging, metrics, tracing
|
|
18
|
+
- Log aggregation: ELK/Loki setup
|
|
19
|
+
- Error tracking: Sentry integration
|
|
20
|
+
- Integration with fullstack-developer workflow
|
|
21
|
+
allowed-tools: [read, write, execute, grep, glob]
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# API Testing & Observability
|
|
25
|
+
|
|
26
|
+
Test contracts, mock dependencies, observe everything.
|
|
27
|
+
|
|
28
|
+
## The Iron Law
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
NO DEPLOY WITHOUT CONTRACT TEST. NO EXTERNAL CALL WITHOUT MOCK. NO PRODUCTION WITHOUT OBSERVABILITY.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start Decision Tree
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
API 测试需求
|
|
40
|
+
│
|
|
41
|
+
▼
|
|
42
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
43
|
+
│ Step 1: 确定测试类型 │
|
|
44
|
+
│ ─────────────────────────────────────────────────────────── │
|
|
45
|
+
│ 单元测试 → 测试单个函数/方法 │
|
|
46
|
+
│ 集成测试 → 测试 API 端点 + 数据库 │
|
|
47
|
+
│ 契约测试 → 验证 API 符合 OpenAPI 规范 │
|
|
48
|
+
│ E2E 测试 → 完整用户流程 │
|
|
49
|
+
└─────────────────────────────────────────────────────────────┘
|
|
50
|
+
│
|
|
51
|
+
▼
|
|
52
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
53
|
+
│ Step 2: 选择工具 │
|
|
54
|
+
│ ─────────────────────────────────────────────────────────── │
|
|
55
|
+
│ Python: pytest + httpx + pytest-asyncio │
|
|
56
|
+
│ Node.js: Jest + Supertest │
|
|
57
|
+
│ 契约测试: Schemathesis / Dredd │
|
|
58
|
+
│ Mock: WireMock / MSW / 自定义 Mock Server │
|
|
59
|
+
└─────────────────────────────────────────────────────────────┘
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
63
|
+
│ Step 3: 设置可观测性 │
|
|
64
|
+
│ ─────────────────────────────────────────────────────────── │
|
|
65
|
+
│ Logging: 结构化日志 + 请求 ID │
|
|
66
|
+
│ Metrics: RED 指标 (Rate, Errors, Duration) │
|
|
67
|
+
│ Tracing: OpenTelemetry 分布式追踪 │
|
|
68
|
+
└─────────────────────────────────────────────────────────────┘
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🔴 Testing Pyramid
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
┌─────────┐
|
|
77
|
+
│ E2E │ 少量,验证关键流程
|
|
78
|
+
│ Tests │
|
|
79
|
+
─┴─────────┴─
|
|
80
|
+
┌─────────────┐
|
|
81
|
+
│ Integration │ 中等,测试 API 端点
|
|
82
|
+
│ Tests │
|
|
83
|
+
─┴─────────────┴─
|
|
84
|
+
┌─────────────────┐
|
|
85
|
+
│ Contract Tests │ 验证 API 契约
|
|
86
|
+
─┴─────────────────┴─
|
|
87
|
+
┌─────────────────────┐
|
|
88
|
+
│ Unit Tests │ 大量,测试业务逻辑
|
|
89
|
+
└─────────────────────┘
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🔴 Contract Testing Protocol (MANDATORY)
|
|
95
|
+
|
|
96
|
+
### Step 1: 契约验证
|
|
97
|
+
|
|
98
|
+
**每个 API 必须通过契约测试:**
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
# tests/contract/test_openapi_compliance.py
|
|
102
|
+
import schemathesis
|
|
103
|
+
|
|
104
|
+
schema = schemathesis.from_path("docs/openapi.yaml")
|
|
105
|
+
|
|
106
|
+
@schema.parametrize()
|
|
107
|
+
def test_api_contract(case):
|
|
108
|
+
"""验证 API 符合 OpenAPI 规范"""
|
|
109
|
+
response = case.call()
|
|
110
|
+
case.validate_response(response)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Step 2: 契约测试清单
|
|
114
|
+
|
|
115
|
+
| 检查项 | 验证内容 |
|
|
116
|
+
|--------|----------|
|
|
117
|
+
| 响应状态码 | 符合 OpenAPI 定义 |
|
|
118
|
+
| 响应结构 | 字段类型、必填字段 |
|
|
119
|
+
| 请求验证 | 参数类型、格式 |
|
|
120
|
+
| 错误响应 | 错误格式一致 |
|
|
121
|
+
| 边界条件 | 空值、超长、特殊字符 |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🔴 Integration Testing
|
|
126
|
+
|
|
127
|
+
### FastAPI 集成测试模板
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
# tests/integration/test_users_api.py
|
|
131
|
+
import pytest
|
|
132
|
+
from httpx import AsyncClient
|
|
133
|
+
from app.main import app
|
|
134
|
+
|
|
135
|
+
@pytest.fixture
|
|
136
|
+
async def client():
|
|
137
|
+
async with AsyncClient(app=app, base_url="http://test") as ac:
|
|
138
|
+
yield ac
|
|
139
|
+
|
|
140
|
+
@pytest.fixture
|
|
141
|
+
async def auth_headers(client):
|
|
142
|
+
"""获取认证 token"""
|
|
143
|
+
response = await client.post("/auth/login", json={
|
|
144
|
+
"username": "test_user",
|
|
145
|
+
"password": "test_password"
|
|
146
|
+
})
|
|
147
|
+
token = response.json()["access_token"]
|
|
148
|
+
return {"Authorization": f"Bearer {token}"}
|
|
149
|
+
|
|
150
|
+
class TestUsersAPI:
|
|
151
|
+
async def test_create_user_success(self, client, auth_headers):
|
|
152
|
+
"""测试创建用户成功"""
|
|
153
|
+
response = await client.post(
|
|
154
|
+
"/api/v1/users",
|
|
155
|
+
json={"username": "newuser", "email": "new@example.com"},
|
|
156
|
+
headers=auth_headers
|
|
157
|
+
)
|
|
158
|
+
assert response.status_code == 201
|
|
159
|
+
assert response.json()["username"] == "newuser"
|
|
160
|
+
|
|
161
|
+
async def test_create_user_duplicate(self, client, auth_headers):
|
|
162
|
+
"""测试重复创建用户"""
|
|
163
|
+
# 先创建一个用户
|
|
164
|
+
await client.post("/api/v1/users", json={...}, headers=auth_headers)
|
|
165
|
+
# 再次创建相同用户
|
|
166
|
+
response = await client.post("/api/v1/users", json={...}, headers=auth_headers)
|
|
167
|
+
assert response.status_code == 409
|
|
168
|
+
|
|
169
|
+
async def test_get_user_not_found(self, client, auth_headers):
|
|
170
|
+
"""测试获取不存在的用户"""
|
|
171
|
+
response = await client.get("/api/v1/users/99999", headers=auth_headers)
|
|
172
|
+
assert response.status_code == 404
|
|
173
|
+
|
|
174
|
+
async def test_unauthorized_access(self, client):
|
|
175
|
+
"""测试未认证访问"""
|
|
176
|
+
response = await client.get("/api/v1/users/1")
|
|
177
|
+
assert response.status_code == 401
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 测试覆盖要求
|
|
181
|
+
|
|
182
|
+
| 场景 | 必须测试 |
|
|
183
|
+
|------|----------|
|
|
184
|
+
| Happy Path | 正常流程成功 |
|
|
185
|
+
| 认证失败 | 401 Unauthorized |
|
|
186
|
+
| 授权失败 | 403 Forbidden |
|
|
187
|
+
| 资源不存在 | 404 Not Found |
|
|
188
|
+
| 输入验证 | 400/422 错误 |
|
|
189
|
+
| 资源冲突 | 409 Conflict |
|
|
190
|
+
| 边界条件 | 空值、极值 |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🔴 Mock Server Protocol
|
|
195
|
+
|
|
196
|
+
### 何时使用 Mock
|
|
197
|
+
|
|
198
|
+
| 场景 | 使用 Mock |
|
|
199
|
+
|------|-----------|
|
|
200
|
+
| 外部 API 依赖 | ✅ 必须 Mock |
|
|
201
|
+
| 数据库 | ❌ 使用测试数据库 |
|
|
202
|
+
| 第三方服务 | ✅ 必须 Mock |
|
|
203
|
+
| 内部微服务 | ✅ 契约测试时 Mock |
|
|
204
|
+
|
|
205
|
+
### Mock Server 实现
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
# tests/mocks/mock_server.py
|
|
209
|
+
from fastapi import FastAPI
|
|
210
|
+
from typing import Dict, Any
|
|
211
|
+
|
|
212
|
+
class MockServer:
|
|
213
|
+
def __init__(self):
|
|
214
|
+
self.app = FastAPI()
|
|
215
|
+
self.stubs: Dict[str, Any] = {}
|
|
216
|
+
self._setup_routes()
|
|
217
|
+
|
|
218
|
+
def stub(self, method: str, path: str, response: dict, status: int = 200):
|
|
219
|
+
"""添加 stub"""
|
|
220
|
+
key = f"{method.upper()}:{path}"
|
|
221
|
+
self.stubs[key] = {"response": response, "status": status}
|
|
222
|
+
|
|
223
|
+
def reset(self):
|
|
224
|
+
"""重置所有 stubs"""
|
|
225
|
+
self.stubs.clear()
|
|
226
|
+
|
|
227
|
+
def _setup_routes(self):
|
|
228
|
+
@self.app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
|
229
|
+
async def handle_request(path: str, request):
|
|
230
|
+
key = f"{request.method}:/{path}"
|
|
231
|
+
if key in self.stubs:
|
|
232
|
+
stub = self.stubs[key]
|
|
233
|
+
return JSONResponse(stub["response"], status_code=stub["status"])
|
|
234
|
+
return JSONResponse({"error": "No stub found"}, status_code=404)
|
|
235
|
+
|
|
236
|
+
# 使用示例
|
|
237
|
+
@pytest.fixture
|
|
238
|
+
async def mock_payment_service():
|
|
239
|
+
server = MockServer()
|
|
240
|
+
server.stub("POST", "/payments", {"id": "pay_123", "status": "success"}, 201)
|
|
241
|
+
# 启动 mock server...
|
|
242
|
+
yield server
|
|
243
|
+
server.reset()
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Scenario-Based Mocking
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
# tests/mocks/scenarios.py
|
|
250
|
+
SCENARIOS = {
|
|
251
|
+
"happy_path": {
|
|
252
|
+
"POST:/auth/login": {"status": 200, "body": {"token": "valid_token"}},
|
|
253
|
+
"GET:/users/1": {"status": 200, "body": {"id": 1, "name": "Test User"}}
|
|
254
|
+
},
|
|
255
|
+
"auth_failure": {
|
|
256
|
+
"POST:/auth/login": {"status": 401, "body": {"error": "Invalid credentials"}}
|
|
257
|
+
},
|
|
258
|
+
"rate_limited": {
|
|
259
|
+
"GET:/api/*": {"status": 429, "body": {"error": "Rate limit exceeded"}}
|
|
260
|
+
},
|
|
261
|
+
"degraded": {
|
|
262
|
+
"GET:/api/*": {"delay": 5000, "status": 200} # 5秒延迟
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 🔴 Observability Setup (MANDATORY)
|
|
270
|
+
|
|
271
|
+
### 三大支柱
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
275
|
+
│ Observability │
|
|
276
|
+
├─────────────────┬─────────────────┬─────────────────────────┤
|
|
277
|
+
│ Logging │ Metrics │ Tracing │
|
|
278
|
+
│ (What happened)│ (How much) │ (Where/How long) │
|
|
279
|
+
├─────────────────┼─────────────────┼─────────────────────────┤
|
|
280
|
+
│ 结构化日志 │ RED 指标 │ 分布式追踪 │
|
|
281
|
+
│ 请求 ID 关联 │ Prometheus │ OpenTelemetry │
|
|
282
|
+
│ 错误堆栈 │ Grafana │ Jaeger/Zipkin │
|
|
283
|
+
└─────────────────┴─────────────────┴─────────────────────────┘
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Structured Logging
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
# core/logging.py
|
|
290
|
+
import structlog
|
|
291
|
+
from uuid import uuid4
|
|
292
|
+
|
|
293
|
+
def setup_logging():
|
|
294
|
+
structlog.configure(
|
|
295
|
+
processors=[
|
|
296
|
+
structlog.processors.TimeStamper(fmt="iso"),
|
|
297
|
+
structlog.processors.add_log_level,
|
|
298
|
+
structlog.processors.JSONRenderer()
|
|
299
|
+
]
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# middleware/request_logging.py
|
|
303
|
+
@app.middleware("http")
|
|
304
|
+
async def log_requests(request: Request, call_next):
|
|
305
|
+
request_id = str(uuid4())
|
|
306
|
+
request.state.request_id = request_id
|
|
307
|
+
|
|
308
|
+
logger = structlog.get_logger().bind(
|
|
309
|
+
request_id=request_id,
|
|
310
|
+
method=request.method,
|
|
311
|
+
path=request.url.path
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
start_time = time.time()
|
|
315
|
+
response = await call_next(request)
|
|
316
|
+
duration = time.time() - start_time
|
|
317
|
+
|
|
318
|
+
logger.info(
|
|
319
|
+
"request_completed",
|
|
320
|
+
status_code=response.status_code,
|
|
321
|
+
duration_ms=round(duration * 1000, 2)
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
response.headers["X-Request-ID"] = request_id
|
|
325
|
+
return response
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### RED Metrics
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
# core/metrics.py
|
|
332
|
+
from prometheus_client import Counter, Histogram
|
|
333
|
+
|
|
334
|
+
# Rate: 请求速率
|
|
335
|
+
REQUEST_COUNT = Counter(
|
|
336
|
+
'http_requests_total',
|
|
337
|
+
'Total HTTP requests',
|
|
338
|
+
['method', 'endpoint', 'status']
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# Errors: 错误率
|
|
342
|
+
ERROR_COUNT = Counter(
|
|
343
|
+
'http_errors_total',
|
|
344
|
+
'Total HTTP errors',
|
|
345
|
+
['method', 'endpoint', 'error_type']
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
# Duration: 响应时间
|
|
349
|
+
REQUEST_DURATION = Histogram(
|
|
350
|
+
'http_request_duration_seconds',
|
|
351
|
+
'HTTP request duration',
|
|
352
|
+
['method', 'endpoint'],
|
|
353
|
+
buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 5.0]
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
# 使用
|
|
357
|
+
@app.middleware("http")
|
|
358
|
+
async def metrics_middleware(request: Request, call_next):
|
|
359
|
+
start = time.time()
|
|
360
|
+
response = await call_next(request)
|
|
361
|
+
duration = time.time() - start
|
|
362
|
+
|
|
363
|
+
REQUEST_COUNT.labels(
|
|
364
|
+
method=request.method,
|
|
365
|
+
endpoint=request.url.path,
|
|
366
|
+
status=response.status_code
|
|
367
|
+
).inc()
|
|
368
|
+
|
|
369
|
+
REQUEST_DURATION.labels(
|
|
370
|
+
method=request.method,
|
|
371
|
+
endpoint=request.url.path
|
|
372
|
+
).observe(duration)
|
|
373
|
+
|
|
374
|
+
return response
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Distributed Tracing
|
|
378
|
+
|
|
379
|
+
```python
|
|
380
|
+
# core/tracing.py
|
|
381
|
+
from opentelemetry import trace
|
|
382
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
|
383
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
384
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
385
|
+
|
|
386
|
+
def setup_tracing(service_name: str):
|
|
387
|
+
provider = TracerProvider()
|
|
388
|
+
processor = BatchSpanProcessor(OTLPSpanExporter())
|
|
389
|
+
provider.add_span_processor(processor)
|
|
390
|
+
trace.set_tracer_provider(provider)
|
|
391
|
+
|
|
392
|
+
tracer = trace.get_tracer(__name__)
|
|
393
|
+
|
|
394
|
+
# 使用
|
|
395
|
+
async def get_user(user_id: int):
|
|
396
|
+
with tracer.start_as_current_span("get_user") as span:
|
|
397
|
+
span.set_attribute("user_id", user_id)
|
|
398
|
+
user = await user_repo.get(user_id)
|
|
399
|
+
if not user:
|
|
400
|
+
span.set_attribute("error", "user_not_found")
|
|
401
|
+
return user
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 🔴 Health Check Endpoints
|
|
407
|
+
|
|
408
|
+
```python
|
|
409
|
+
# api/health.py
|
|
410
|
+
from fastapi import APIRouter
|
|
411
|
+
from pydantic import BaseModel
|
|
412
|
+
|
|
413
|
+
router = APIRouter()
|
|
414
|
+
|
|
415
|
+
class HealthResponse(BaseModel):
|
|
416
|
+
status: str
|
|
417
|
+
version: str
|
|
418
|
+
dependencies: dict
|
|
419
|
+
|
|
420
|
+
@router.get("/health/live")
|
|
421
|
+
async def liveness():
|
|
422
|
+
"""Kubernetes liveness probe"""
|
|
423
|
+
return {"status": "ok"}
|
|
424
|
+
|
|
425
|
+
@router.get("/health/ready")
|
|
426
|
+
async def readiness():
|
|
427
|
+
"""Kubernetes readiness probe"""
|
|
428
|
+
checks = {
|
|
429
|
+
"database": await check_database(),
|
|
430
|
+
"redis": await check_redis(),
|
|
431
|
+
"external_api": await check_external_api()
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
all_healthy = all(c["healthy"] for c in checks.values())
|
|
435
|
+
status = "ok" if all_healthy else "degraded"
|
|
436
|
+
|
|
437
|
+
return HealthResponse(
|
|
438
|
+
status=status,
|
|
439
|
+
version=settings.VERSION,
|
|
440
|
+
dependencies=checks
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
async def check_database():
|
|
444
|
+
try:
|
|
445
|
+
await db.execute("SELECT 1")
|
|
446
|
+
return {"healthy": True, "latency_ms": 5}
|
|
447
|
+
except Exception as e:
|
|
448
|
+
return {"healthy": False, "error": str(e)}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## 🔴 Deep Logging (from log-analysis)
|
|
454
|
+
|
|
455
|
+
### 日志级别规范
|
|
456
|
+
|
|
457
|
+
| 级别 | 用途 | 示例 |
|
|
458
|
+
|------|------|------|
|
|
459
|
+
| **ERROR** | 需要立即处理 | 数据库连接失败、支付失败 |
|
|
460
|
+
| **WARN** | 潜在问题 | 重试成功、降级处理 |
|
|
461
|
+
| **INFO** | 关键业务事件 | 用户登录、订单创建 |
|
|
462
|
+
| **DEBUG** | 调试信息 | 函数参数、中间状态 |
|
|
463
|
+
|
|
464
|
+
### 敏感信息脱敏
|
|
465
|
+
|
|
466
|
+
```python
|
|
467
|
+
SENSITIVE_FIELDS = {'password', 'token', 'secret', 'credit_card'}
|
|
468
|
+
|
|
469
|
+
def mask_sensitive(event_dict):
|
|
470
|
+
for key in event_dict:
|
|
471
|
+
if any(s in key.lower() for s in SENSITIVE_FIELDS):
|
|
472
|
+
event_dict[key] = "***MASKED***"
|
|
473
|
+
return event_dict
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### 日志聚合 (ELK/Loki)
|
|
477
|
+
|
|
478
|
+
```yaml
|
|
479
|
+
# ELK Stack
|
|
480
|
+
services:
|
|
481
|
+
elasticsearch:
|
|
482
|
+
image: elasticsearch:8.11.0
|
|
483
|
+
logstash:
|
|
484
|
+
image: logstash:8.11.0
|
|
485
|
+
kibana:
|
|
486
|
+
image: kibana:8.11.0
|
|
487
|
+
|
|
488
|
+
# Loki + Grafana
|
|
489
|
+
services:
|
|
490
|
+
loki:
|
|
491
|
+
image: grafana/loki:2.9.0
|
|
492
|
+
grafana:
|
|
493
|
+
image: grafana/grafana:latest
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### 日志查询
|
|
497
|
+
|
|
498
|
+
```
|
|
499
|
+
# Kibana KQL
|
|
500
|
+
level: "error" AND service: "api"
|
|
501
|
+
duration_ms > 1000
|
|
502
|
+
|
|
503
|
+
# Loki LogQL
|
|
504
|
+
{app="api"} | json | level="error"
|
|
505
|
+
sum(rate({app="api"} |= "error" [5m]))
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### 错误追踪 (Sentry)
|
|
509
|
+
|
|
510
|
+
```python
|
|
511
|
+
import sentry_sdk
|
|
512
|
+
from sentry_sdk.integrations.fastapi import FastApiIntegration
|
|
513
|
+
|
|
514
|
+
sentry_sdk.init(
|
|
515
|
+
dsn="https://xxx@sentry.io/xxx",
|
|
516
|
+
integrations=[FastApiIntegration()],
|
|
517
|
+
traces_sample_rate=0.1,
|
|
518
|
+
)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## Agent 路由
|
|
524
|
+
|
|
525
|
+
| 任务类型 | 调用 Agent/Command |
|
|
526
|
+
|----------|-------------------|
|
|
527
|
+
| API 文档生成 | `agents/api-documenter.md` |
|
|
528
|
+
| Mock Server | `commands/api-mock.md` |
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## 与 fullstack-developer 集成
|
|
533
|
+
|
|
534
|
+
### 调用时机
|
|
535
|
+
|
|
536
|
+
```
|
|
537
|
+
fullstack-developer Phase 5 (测试验证)
|
|
538
|
+
│
|
|
539
|
+
├── API 开发完成?
|
|
540
|
+
│ ↓
|
|
541
|
+
│ api-testing-observability
|
|
542
|
+
│ │
|
|
543
|
+
│ ├── 契约测试
|
|
544
|
+
│ ├── 集成测试
|
|
545
|
+
│ ├── 设置可观测性
|
|
546
|
+
│ └── 返回: 测试报告 + 覆盖率
|
|
547
|
+
│
|
|
548
|
+
└── 继续 Phase 6 (code-review)
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### 输出要求
|
|
552
|
+
|
|
553
|
+
```markdown
|
|
554
|
+
## API Testing 完成报告
|
|
555
|
+
|
|
556
|
+
### 测试覆盖
|
|
557
|
+
| 类型 | 通过 | 失败 | 覆盖率 |
|
|
558
|
+
|------|------|------|--------|
|
|
559
|
+
| 单元测试 | 45 | 0 | 85% |
|
|
560
|
+
| 集成测试 | 20 | 0 | 100% |
|
|
561
|
+
| 契约测试 | 15 | 0 | 100% |
|
|
562
|
+
|
|
563
|
+
### 可观测性
|
|
564
|
+
- [ ] 结构化日志: ✅
|
|
565
|
+
- [ ] RED 指标: ✅
|
|
566
|
+
- [ ] 分布式追踪: ✅
|
|
567
|
+
- [ ] Health Check: ✅
|
|
568
|
+
|
|
569
|
+
### Mock 配置
|
|
570
|
+
- 外部服务 Mock: 3 个
|
|
571
|
+
- 场景覆盖: happy_path, error, degraded
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
## Reference Navigation
|
|
577
|
+
|
|
578
|
+
| Situation | Read This |
|
|
579
|
+
|-----------|-----------|
|
|
580
|
+
| API 文档 | `agents/api-documenter.md` |
|
|
581
|
+
| Mock Server | `commands/api-mock.md` |
|
|
582
|
+
| API 脚手架 | `../api-scaffolding/SKILL.md` |
|
|
583
|
+
| 测试模式 | `../test-driven-development/SKILL.md` |
|