qa-skills 3.0.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/README.md +168 -0
- package/bin/cli.js +42 -0
- package/dist/agents/registry.d.ts +5 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +101 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +9 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/dependencies.d.ts +21 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +125 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/installer.d.ts +25 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +437 -0
- package/dist/installer.js.map +1 -0
- package/dist/scaffold.d.ts +27 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +182 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +40 -0
- package/skills/qa-accessibility-test-writer/SKILL.md +127 -0
- package/skills/qa-accessibility-test-writer/references/axe-core-patterns.md +349 -0
- package/skills/qa-accessibility-test-writer/references/best-practices.md +184 -0
- package/skills/qa-accessibility-test-writer/references/wcag-tests.md +331 -0
- package/skills/qa-api-contract-curator/SKILL.md +104 -0
- package/skills/qa-api-contract-curator/references/breaking-changes.md +363 -0
- package/skills/qa-api-contract-curator/references/openapi-structure.md +404 -0
- package/skills/qa-browser-data-collector/SKILL.md +132 -0
- package/skills/qa-browser-data-collector/references/data-collection-checklist.md +91 -0
- package/skills/qa-browser-data-collector/references/playwright-mcp-patterns.md +113 -0
- package/skills/qa-bug-ticket-creator/SKILL.md +148 -0
- package/skills/qa-bug-ticket-creator/references/bug-report-format.md +149 -0
- package/skills/qa-bug-ticket-creator/references/severity-guide.md +81 -0
- package/skills/qa-bug-ticket-creator/templates/bug-ticket-template.md +39 -0
- package/skills/qa-changelog-analyzer/SKILL.md +134 -0
- package/skills/qa-changelog-analyzer/references/git-analysis-patterns.md +138 -0
- package/skills/qa-changelog-analyzer/references/impact-mapping.md +120 -0
- package/skills/qa-clickup-integration/SKILL.md +166 -0
- package/skills/qa-clickup-integration/references/api-patterns.md +102 -0
- package/skills/qa-clickup-integration/references/field-mapping.md +71 -0
- package/skills/qa-codeceptjs-writer/SKILL.md +136 -0
- package/skills/qa-codeceptjs-writer/references/best-practices.md +207 -0
- package/skills/qa-codeceptjs-writer/references/config.md +255 -0
- package/skills/qa-codeceptjs-writer/references/patterns.md +285 -0
- package/skills/qa-coverage-analyzer/SKILL.md +166 -0
- package/skills/qa-coverage-analyzer/references/best-practices.md +142 -0
- package/skills/qa-coverage-analyzer/references/coverage-dimensions.md +155 -0
- package/skills/qa-coverage-analyzer/references/tools.md +204 -0
- package/skills/qa-cypress-writer/SKILL.md +134 -0
- package/skills/qa-cypress-writer/references/assertions.md +121 -0
- package/skills/qa-cypress-writer/references/best-practices.md +82 -0
- package/skills/qa-cypress-writer/references/config.md +121 -0
- package/skills/qa-cypress-writer/references/patterns.md +170 -0
- package/skills/qa-data-factory/SKILL.md +126 -0
- package/skills/qa-data-factory/references/factory-patterns.md +164 -0
- package/skills/qa-data-factory/references/faker-guide.md +131 -0
- package/skills/qa-diagram-generator/SKILL.md +125 -0
- package/skills/qa-diagram-generator/references/c4-model.md +53 -0
- package/skills/qa-diagram-generator/references/charts.md +58 -0
- package/skills/qa-diagram-generator/references/class-diagram.md +85 -0
- package/skills/qa-diagram-generator/references/er-diagram.md +69 -0
- package/skills/qa-diagram-generator/references/flowchart.md +92 -0
- package/skills/qa-diagram-generator/references/from-screenshot.md +45 -0
- package/skills/qa-diagram-generator/references/gantt.md +49 -0
- package/skills/qa-diagram-generator/references/journey.md +50 -0
- package/skills/qa-diagram-generator/references/mindmap.md +75 -0
- package/skills/qa-diagram-generator/references/sequence.md +69 -0
- package/skills/qa-diagram-generator/references/state-diagram.md +56 -0
- package/skills/qa-discovery-interview/SKILL.md +182 -0
- package/skills/qa-discovery-interview/references/completeness-checklist.md +53 -0
- package/skills/qa-discovery-interview/references/conflict-patterns.md +101 -0
- package/skills/qa-discovery-interview/references/qa-categories.md +147 -0
- package/skills/qa-discovery-interview/templates/qa-brief-template.md +168 -0
- package/skills/qa-environment-checker/SKILL.md +142 -0
- package/skills/qa-environment-checker/references/dependency-matrix.md +101 -0
- package/skills/qa-environment-checker/references/health-checks.md +209 -0
- package/skills/qa-environment-checker/templates/env-readiness-template.md +64 -0
- package/skills/qa-flaky-detector/SKILL.md +153 -0
- package/skills/qa-flaky-detector/references/ci-analysis.md +140 -0
- package/skills/qa-flaky-detector/references/flaky-patterns.md +247 -0
- package/skills/qa-github-issues-enhanced/SKILL.md +175 -0
- package/skills/qa-github-issues-enhanced/references/issue-templates.md +425 -0
- package/skills/qa-github-issues-enhanced/references/label-taxonomy.md +130 -0
- package/skills/qa-github-issues-enhanced/references/workflow-patterns.md +188 -0
- package/skills/qa-httpx-writer/SKILL.md +138 -0
- package/skills/qa-httpx-writer/references/assertions.md +195 -0
- package/skills/qa-httpx-writer/references/best-practices.md +140 -0
- package/skills/qa-httpx-writer/references/config.md +212 -0
- package/skills/qa-httpx-writer/references/patterns.md +262 -0
- package/skills/qa-jest-writer/SKILL.md +131 -0
- package/skills/qa-jest-writer/references/assertions.md +125 -0
- package/skills/qa-jest-writer/references/best-practices.md +136 -0
- package/skills/qa-jest-writer/references/config.md +134 -0
- package/skills/qa-jest-writer/references/patterns.md +172 -0
- package/skills/qa-jira-integration/SKILL.md +135 -0
- package/skills/qa-jira-integration/references/api-patterns.md +143 -0
- package/skills/qa-jira-integration/references/field-mapping.md +79 -0
- package/skills/qa-jira-integration/references/xray-integration.md +85 -0
- package/skills/qa-jmeter-writer/SKILL.md +171 -0
- package/skills/qa-jmeter-writer/references/best-practices.md +157 -0
- package/skills/qa-jmeter-writer/references/config.md +204 -0
- package/skills/qa-jmeter-writer/references/patterns.md +242 -0
- package/skills/qa-junit5-writer/SKILL.md +157 -0
- package/skills/qa-junit5-writer/references/assertions.md +118 -0
- package/skills/qa-junit5-writer/references/config.md +97 -0
- package/skills/qa-junit5-writer/references/patterns.md +162 -0
- package/skills/qa-k6-writer/SKILL.md +155 -0
- package/skills/qa-k6-writer/references/best-practices.md +236 -0
- package/skills/qa-k6-writer/references/config.md +219 -0
- package/skills/qa-k6-writer/references/patterns.md +304 -0
- package/skills/qa-linear-integration/SKILL.md +137 -0
- package/skills/qa-linear-integration/references/api-patterns.md +249 -0
- package/skills/qa-linear-integration/references/field-mapping.md +121 -0
- package/skills/qa-locust-writer/SKILL.md +151 -0
- package/skills/qa-locust-writer/references/best-practices.md +126 -0
- package/skills/qa-locust-writer/references/config.md +170 -0
- package/skills/qa-locust-writer/references/patterns.md +235 -0
- package/skills/qa-manual-test-designer/SKILL.md +145 -0
- package/skills/qa-manual-test-designer/references/exploratory-charters.md +138 -0
- package/skills/qa-manual-test-designer/references/personas.md +146 -0
- package/skills/qa-manual-test-designer/templates/exploratory-charter-template.md +47 -0
- package/skills/qa-manual-test-designer/templates/test-case-template.md +31 -0
- package/skills/qa-mobile-test-writer/SKILL.md +144 -0
- package/skills/qa-mobile-test-writer/references/best-practices.md +214 -0
- package/skills/qa-mobile-test-writer/references/config.md +309 -0
- package/skills/qa-mobile-test-writer/references/patterns.md +304 -0
- package/skills/qa-nfr-analyst/SKILL.md +177 -0
- package/skills/qa-nfr-analyst/references/iso-25010-model.md +159 -0
- package/skills/qa-nfr-analyst/references/owasp-wstg-baseline.md +202 -0
- package/skills/qa-nfr-analyst/references/wcag-checklist.md +184 -0
- package/skills/qa-nfr-analyst/templates/owasp-checklist-template.md +89 -0
- package/skills/qa-nfr-analyst/templates/wcag-checklist-template.md +48 -0
- package/skills/qa-orchestrator/SKILL.md +132 -0
- package/skills/qa-orchestrator/references/handoff-chains.md +105 -0
- package/skills/qa-orchestrator/references/pipeline-modes.md +115 -0
- package/skills/qa-orchestrator/references/scheduler-rules.md +84 -0
- package/skills/qa-pact-writer/SKILL.md +133 -0
- package/skills/qa-pact-writer/references/best-practices.md +100 -0
- package/skills/qa-pact-writer/references/config.md +135 -0
- package/skills/qa-pact-writer/references/patterns.md +161 -0
- package/skills/qa-plan-creator/SKILL.md +139 -0
- package/skills/qa-plan-creator/references/introduction-plan.md +43 -0
- package/skills/qa-plan-creator/references/migration-plan.md +44 -0
- package/skills/qa-plan-creator/references/onboarding-plan.md +46 -0
- package/skills/qa-plan-creator/references/performance-plan.md +44 -0
- package/skills/qa-plan-creator/references/regression-plan.md +45 -0
- package/skills/qa-plan-creator/references/release-plan.md +45 -0
- package/skills/qa-plan-creator/references/sprint-plan.md +44 -0
- package/skills/qa-plan-creator/references/test-plan.md +59 -0
- package/skills/qa-plan-creator/references/uat-plan.md +43 -0
- package/skills/qa-plan-creator/templates/checklist-template.md +36 -0
- package/skills/qa-plan-creator/templates/regression-checklist-template.md +49 -0
- package/skills/qa-plan-creator/templates/release-checklist-template.md +46 -0
- package/skills/qa-plan-creator/templates/test-plan-template.md +74 -0
- package/skills/qa-playwright-py-writer/SKILL.md +156 -0
- package/skills/qa-playwright-py-writer/references/best-practices.md +194 -0
- package/skills/qa-playwright-py-writer/references/config.md +195 -0
- package/skills/qa-playwright-py-writer/references/patterns.md +212 -0
- package/skills/qa-playwright-ts-writer/SKILL.md +151 -0
- package/skills/qa-playwright-ts-writer/references/assertions.md +109 -0
- package/skills/qa-playwright-ts-writer/references/best-practices.md +191 -0
- package/skills/qa-playwright-ts-writer/references/config.md +144 -0
- package/skills/qa-playwright-ts-writer/references/patterns.md +171 -0
- package/skills/qa-pytest-writer/SKILL.md +145 -0
- package/skills/qa-pytest-writer/references/assertions.md +149 -0
- package/skills/qa-pytest-writer/references/best-practices.md +97 -0
- package/skills/qa-pytest-writer/references/config.md +176 -0
- package/skills/qa-pytest-writer/references/patterns.md +251 -0
- package/skills/qa-qase-integration/SKILL.md +149 -0
- package/skills/qa-qase-integration/references/api-reference.md +354 -0
- package/skills/qa-qase-integration/references/ci-integration.md +196 -0
- package/skills/qa-qase-integration/references/field-mapping.md +157 -0
- package/skills/qa-requirements-generator/SKILL.md +152 -0
- package/skills/qa-requirements-generator/references/iso-29148-structure.md +153 -0
- package/skills/qa-requirements-generator/references/requirement-patterns.md +278 -0
- package/skills/qa-rest-assured-writer/SKILL.md +137 -0
- package/skills/qa-rest-assured-writer/references/best-practices.md +50 -0
- package/skills/qa-rest-assured-writer/references/config.md +124 -0
- package/skills/qa-rest-assured-writer/references/patterns.md +192 -0
- package/skills/qa-risk-analyzer/SKILL.md +158 -0
- package/skills/qa-risk-analyzer/references/impact-analysis.md +133 -0
- package/skills/qa-risk-analyzer/references/risk-factors.md +123 -0
- package/skills/qa-robot-framework-writer/SKILL.md +147 -0
- package/skills/qa-robot-framework-writer/references/best-practices.md +249 -0
- package/skills/qa-robot-framework-writer/references/config.md +204 -0
- package/skills/qa-robot-framework-writer/references/libraries.md +273 -0
- package/skills/qa-robot-framework-writer/references/patterns.md +216 -0
- package/skills/qa-security-test-writer/SKILL.md +123 -0
- package/skills/qa-security-test-writer/references/best-practices.md +155 -0
- package/skills/qa-security-test-writer/references/owasp-top10.md +331 -0
- package/skills/qa-security-test-writer/references/zap-config.md +258 -0
- package/skills/qa-selenium-java-writer/SKILL.md +143 -0
- package/skills/qa-selenium-java-writer/references/best-practices.md +59 -0
- package/skills/qa-selenium-java-writer/references/config.md +143 -0
- package/skills/qa-selenium-java-writer/references/patterns.md +170 -0
- package/skills/qa-selenium-py-writer/SKILL.md +150 -0
- package/skills/qa-selenium-py-writer/references/best-practices.md +175 -0
- package/skills/qa-selenium-py-writer/references/config.md +224 -0
- package/skills/qa-selenium-py-writer/references/patterns.md +255 -0
- package/skills/qa-shortcut-integration/SKILL.md +143 -0
- package/skills/qa-shortcut-integration/references/api-patterns.md +126 -0
- package/skills/qa-shortcut-integration/references/field-mapping.md +66 -0
- package/skills/qa-spec-auditor/SKILL.md +162 -0
- package/skills/qa-spec-auditor/references/audit-checklist.md +144 -0
- package/skills/qa-spec-auditor/references/drift-patterns.md +207 -0
- package/skills/qa-spec-writer/SKILL.md +143 -0
- package/skills/qa-spec-writer/references/gherkin-guide.md +253 -0
- package/skills/qa-spec-writer/references/specification-patterns.md +274 -0
- package/skills/qa-spring-test-writer/SKILL.md +170 -0
- package/skills/qa-spring-test-writer/references/best-practices.md +57 -0
- package/skills/qa-spring-test-writer/references/config.md +179 -0
- package/skills/qa-spring-test-writer/references/patterns.md +235 -0
- package/skills/qa-supertest-writer/SKILL.md +150 -0
- package/skills/qa-supertest-writer/references/assertions.md +192 -0
- package/skills/qa-supertest-writer/references/best-practices.md +102 -0
- package/skills/qa-supertest-writer/references/config.md +166 -0
- package/skills/qa-supertest-writer/references/patterns.md +242 -0
- package/skills/qa-task-creator/SKILL.md +142 -0
- package/skills/qa-task-creator/references/linking-patterns.md +127 -0
- package/skills/qa-task-creator/references/task-types.md +169 -0
- package/skills/qa-task-creator/templates/task-template.md +24 -0
- package/skills/qa-test-doc-compiler/SKILL.md +114 -0
- package/skills/qa-test-doc-compiler/references/agile-tailoring.md +220 -0
- package/skills/qa-test-doc-compiler/references/iso-29119-3-documents.md +302 -0
- package/skills/qa-test-healer/SKILL.md +101 -0
- package/skills/qa-test-healer/references/diagnosis-patterns.md +142 -0
- package/skills/qa-test-healer/references/fix-strategies.md +177 -0
- package/skills/qa-test-reporter/SKILL.md +130 -0
- package/skills/qa-test-reporter/references/best-practices.md +162 -0
- package/skills/qa-test-reporter/references/iso-29119-reports.md +236 -0
- package/skills/qa-test-reporter/references/report-formats.md +287 -0
- package/skills/qa-test-reviewer/SKILL.md +142 -0
- package/skills/qa-test-reviewer/references/anti-patterns.md +268 -0
- package/skills/qa-test-reviewer/references/review-checklist.md +93 -0
- package/skills/qa-test-strategy/SKILL.md +133 -0
- package/skills/qa-test-strategy/references/entry-exit-criteria.md +176 -0
- package/skills/qa-test-strategy/references/risk-matrix.md +102 -0
- package/skills/qa-test-strategy/references/testing-types.md +143 -0
- package/skills/qa-testcase-from-docs/SKILL.md +161 -0
- package/skills/qa-testcase-from-docs/references/test-case-format.md +196 -0
- package/skills/qa-testcase-from-docs/references/test-design-techniques.md +126 -0
- package/skills/qa-testcase-from-docs/templates/test-case-template.md +31 -0
- package/skills/qa-testcase-from-ui/SKILL.md +109 -0
- package/skills/qa-testcase-from-ui/references/ui-element-patterns.md +126 -0
- package/skills/qa-testcase-from-ui/references/visual-analysis-guide.md +146 -0
- package/skills/qa-testcase-from-ui/templates/test-case-template.md +31 -0
- package/skills/qa-visual-regression-writer/SKILL.md +175 -0
- package/skills/qa-visual-regression-writer/references/best-practices.md +154 -0
- package/skills/qa-visual-regression-writer/references/config.md +220 -0
- package/skills/qa-visual-regression-writer/references/patterns.md +213 -0
- package/skills/qa-vitest-writer/SKILL.md +141 -0
- package/skills/qa-vitest-writer/references/assertions.md +105 -0
- package/skills/qa-vitest-writer/references/best-practices.md +62 -0
- package/skills/qa-vitest-writer/references/config.md +127 -0
- package/skills/qa-vitest-writer/references/patterns.md +141 -0
- package/skills/qa-webdriverio-writer/SKILL.md +145 -0
- package/skills/qa-webdriverio-writer/references/best-practices.md +176 -0
- package/skills/qa-webdriverio-writer/references/config.md +240 -0
- package/skills/qa-webdriverio-writer/references/patterns.md +269 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Label Taxonomy for QA GitHub Issues
|
|
2
|
+
|
|
3
|
+
*Complete label taxonomy with naming conventions and color codes for GitHub Issues.*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Naming Conventions
|
|
8
|
+
|
|
9
|
+
- **Prefix format**: `category/value` (e.g., `type/bug`, `priority/high`)
|
|
10
|
+
- **Flat labels**: Use for simple tags without hierarchy (e.g., `needs-triage`, `verified`)
|
|
11
|
+
- **Lowercase**: All labels use lowercase with hyphens
|
|
12
|
+
- **Consistent**: Same prefix for same category across all labels
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Type Labels (`type/`)
|
|
17
|
+
|
|
18
|
+
| Label | Color | Description |
|
|
19
|
+
| ----- | ----- | ----------- |
|
|
20
|
+
| `type/bug` | `#d73a4a` (red) | Defect or incorrect behavior |
|
|
21
|
+
| `type/enhancement` | `#a2eeef` (cyan) | New feature or improvement |
|
|
22
|
+
| `type/task` | `#7f8c8d` (gray) | Work item, chore, or maintenance |
|
|
23
|
+
| `type/documentation` | `#0075ca` (blue) | Docs, specs, or README updates |
|
|
24
|
+
| `type/test-coverage-gap` | `#fbca04` (yellow) | Missing or insufficient test coverage |
|
|
25
|
+
| `type/flaky-test` | `#f9d0c4` (light red) | Intermittent or unreliable test |
|
|
26
|
+
| `type/security` | `#ee0701` (dark red) | Security vulnerability or hardening |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Priority Labels (`priority/`)
|
|
31
|
+
|
|
32
|
+
| Label | Color | Description |
|
|
33
|
+
| ----- | ----- | ----------- |
|
|
34
|
+
| `priority/critical` | `#b60205` (dark red) | Fix immediately; blocks release |
|
|
35
|
+
| `priority/high` | `#d93f0b` (orange-red) | Fix in current sprint |
|
|
36
|
+
| `priority/medium` | `#fbca04` (yellow) | Fix in next sprint |
|
|
37
|
+
| `priority/low` | `#0e8a16` (green) | Backlog; fix when possible |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Component Labels (`component/`)
|
|
42
|
+
|
|
43
|
+
| Label | Color | Description |
|
|
44
|
+
| ----- | ----- | ----------- |
|
|
45
|
+
| `component/frontend` | `#1d76db` (blue) | UI, React, Vue, Angular |
|
|
46
|
+
| `component/backend` | `#5319e7` (purple) | Server, services, business logic |
|
|
47
|
+
| `component/api` | `#0052cc` (blue) | REST, GraphQL, gRPC endpoints |
|
|
48
|
+
| `component/auth` | `#c5def5` (light blue) | Login, auth, permissions |
|
|
49
|
+
| `component/database` | `#bfdadc` (light gray) | DB, migrations, queries |
|
|
50
|
+
| `component/integration` | `#c2e0c6` (light green) | Third-party, external services |
|
|
51
|
+
| `component/mobile` | `#bfd4f2` (light blue) | iOS, Android, mobile web |
|
|
52
|
+
| `component/e2e` | `#d4c5f9` (lavender) | End-to-end tests |
|
|
53
|
+
| `component/unit` | `#fef2c0` (light yellow) | Unit tests |
|
|
54
|
+
| `component/performance` | `#f9d0c4` (light red) | Load, stress, performance tests |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Status Labels (`status/`)
|
|
59
|
+
|
|
60
|
+
| Label | Color | Description |
|
|
61
|
+
| ----- | ----- | ----------- |
|
|
62
|
+
| `status/needs-triage` | `#d93f0b` (orange) | New; awaiting review |
|
|
63
|
+
| `status/in-progress` | `#0052cc` (blue) | Being worked on |
|
|
64
|
+
| `status/ready-for-test` | `#0e8a16` (green) | PR merged; QA verification pending |
|
|
65
|
+
| `status/verified` | `#0e8a16` (green) | QA confirmed fix |
|
|
66
|
+
| `status/blocked` | `#b60205` (red) | Waiting on dependency |
|
|
67
|
+
| `status/wontfix` | `#ffffff` (white) | Declined; out of scope |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## QA-Specific Labels
|
|
72
|
+
|
|
73
|
+
| Label | Color | Description |
|
|
74
|
+
| ----- | ----- | ----------- |
|
|
75
|
+
| `docs-update` | `#0075ca` (blue) | Documentation change |
|
|
76
|
+
| `spec-drift` | `#fbca04` (yellow) | Spec-auditor finding; spec vs implementation |
|
|
77
|
+
| `regression-risk` | `#f9d0c4` (light red) | Changelog-analyzer flagged |
|
|
78
|
+
| `needs-repro` | `#d93f0b` (orange) | Cannot reproduce; needs more info |
|
|
79
|
+
| `duplicate` | `#cfd3d7` (gray) | Duplicate of another issue |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Color Reference (Hex Codes)
|
|
84
|
+
|
|
85
|
+
| Color Name | Hex | Use |
|
|
86
|
+
| ---------- | --- | --- |
|
|
87
|
+
| Red (critical) | `#d73a4a` | Bugs, critical priority |
|
|
88
|
+
| Dark red | `#b60205` | Blockers, critical |
|
|
89
|
+
| Orange | `#d93f0b` | High priority, needs attention |
|
|
90
|
+
| Yellow | `#fbca04` | Medium priority, warnings |
|
|
91
|
+
| Green | `#0e8a16` | Done, verified, low priority |
|
|
92
|
+
| Blue | `#0052cc` | In progress, API, info |
|
|
93
|
+
| Cyan | `#a2eeef` | Enhancements |
|
|
94
|
+
| Purple | `#5319e7` | Backend, special |
|
|
95
|
+
| Gray | `#7f8c8d` | Tasks, neutral |
|
|
96
|
+
| Light gray | `#cfd3d7` | Duplicates, deprecated |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## GitHub Label Creation
|
|
101
|
+
|
|
102
|
+
To create labels via GitHub MCP or API:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"name": "type/bug",
|
|
107
|
+
"color": "d73a4a",
|
|
108
|
+
"description": "Defect or incorrect behavior"
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Note**: GitHub expects 6-character hex without `#`. Use lowercase.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Recommended Label Sets by Repo Type
|
|
117
|
+
|
|
118
|
+
| Repo Type | Essential Labels |
|
|
119
|
+
| --------- | ----------------- |
|
|
120
|
+
| **QA-focused** | `type/bug`, `type/test-coverage-gap`, `type/flaky-test`, `type/documentation`, `priority/*`, `component/*`, `status/*` |
|
|
121
|
+
| **Full-stack** | All `type/`, `priority/`, `component/`, `status/` |
|
|
122
|
+
| **Minimal** | `type/bug`, `type/enhancement`, `priority/high`, `priority/medium`, `status/needs-triage`, `status/in-progress` |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Customization
|
|
127
|
+
|
|
128
|
+
- Add project-specific components (e.g., `component/checkout`, `component/search`)
|
|
129
|
+
- Add team labels (e.g., `team/qa`, `team/platform`)
|
|
130
|
+
- Add sprint/release labels if not using milestones (e.g., `sprint/24-01`)
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Structured Workflow Patterns for QA GitHub Issues
|
|
2
|
+
|
|
3
|
+
*Workflow patterns: bug lifecycle, coverage gap → task → PR, flaky test → investigation → fix.*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Bug Lifecycle Workflow
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
[Report] → [Triage] → [Fix] → [Verify] → [Close]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### States and Labels
|
|
14
|
+
|
|
15
|
+
| Stage | Status Label | Actions |
|
|
16
|
+
| ----- | ------------ | ------- |
|
|
17
|
+
| **Report** | `status/needs-triage` | Create issue with `type/bug`; assign severity, component |
|
|
18
|
+
| **Triage** | — | Confirm reproducibility; add `priority/*`; assign |
|
|
19
|
+
| **Fix** | `status/in-progress` | Dev creates PR; link with "Fixes #N" |
|
|
20
|
+
| **Verify** | `status/ready-for-test` | PR merged; QA runs verification tests |
|
|
21
|
+
| **Close** | `status/verified` | QA confirms; close issue |
|
|
22
|
+
|
|
23
|
+
### Transitions
|
|
24
|
+
|
|
25
|
+
1. **Report → Triage**: Assignee reviews; adds `priority/critical` or `priority/high` if valid
|
|
26
|
+
2. **Triage → Fix**: Assign to dev; set `status/in-progress`
|
|
27
|
+
3. **Fix → Verify**: PR merged; auto or manual set `status/ready-for-test`
|
|
28
|
+
4. **Verify → Close**: QA passes verification; set `status/verified`; close
|
|
29
|
+
|
|
30
|
+
### Automation Hints
|
|
31
|
+
|
|
32
|
+
- **GitHub Actions**: On PR merge with "Fixes #N", add `status/ready-for-test` to linked issue
|
|
33
|
+
- **GitHub MCP**: When creating bug from test failure, auto-assign `type/bug`, `status/needs-triage`, `component/*`
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Coverage Gap → Task → PR Workflow
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
[Coverage Analyzer] → [Coverage Gap Issue] → [Fix Task] → [PR] → [Verify]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Flow
|
|
44
|
+
|
|
45
|
+
1. **qa-coverage-analyzer** produces gap report (file:line, module, risk)
|
|
46
|
+
2. **qa-github-issues-enhanced** creates `type/test-coverage-gap` issue with:
|
|
47
|
+
- Location (file:line)
|
|
48
|
+
- Coverage type (code/requirement/technique)
|
|
49
|
+
- Rationale (risk, complexity)
|
|
50
|
+
- Suggested tests
|
|
51
|
+
3. **qa-task-creator** (or this skill) creates linked **fix task**:
|
|
52
|
+
- Title: "Add tests for [module/function]"
|
|
53
|
+
- Links to coverage gap issue
|
|
54
|
+
- Labels: `type/task`, `component/unit` or `component/e2e`
|
|
55
|
+
4. Dev implements tests; opens PR referencing both issues
|
|
56
|
+
5. PR merged; coverage gap and task closed
|
|
57
|
+
|
|
58
|
+
### Issue Linking
|
|
59
|
+
|
|
60
|
+
- Coverage gap issue: `#123`
|
|
61
|
+
- Fix task: "Adds tests per #123" or "Closes #123"
|
|
62
|
+
- PR: "Fixes #124" (fix task) — optionally "Addresses #123" (coverage gap)
|
|
63
|
+
|
|
64
|
+
### Bulk Creation
|
|
65
|
+
|
|
66
|
+
When coverage analyzer outputs many gaps:
|
|
67
|
+
|
|
68
|
+
1. Group by component and priority
|
|
69
|
+
2. Create one issue per gap (or batch similar gaps into single issue)
|
|
70
|
+
3. Use bulk-create API; assign same milestone
|
|
71
|
+
4. Optionally create fix tasks in batch via qa-task-creator
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 3. Flaky Test → Investigation → Fix Workflow
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
[Flaky Report] → [Investigation] → [Root Cause] → [Fix] → [Verify]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Flow
|
|
82
|
+
|
|
83
|
+
1. **qa-flaky-detector** or manual report creates `type/flaky-test` issue
|
|
84
|
+
2. **Investigation**: Assign to dev/QA; add `status/in-progress`
|
|
85
|
+
- Run test in loop; capture failure pattern
|
|
86
|
+
- Classify: race-condition, shared-state, time-dependency, external-dependency
|
|
87
|
+
3. **Root cause**: Update issue with findings; create fix task if needed
|
|
88
|
+
4. **Fix**: Dev fixes test or code; PR with "Fixes #N"
|
|
89
|
+
5. **Verify**: Run test 50+ times in CI; confirm stability; close
|
|
90
|
+
|
|
91
|
+
### Labels by Pattern
|
|
92
|
+
|
|
93
|
+
| Flaky Pattern | Suggested Labels | Fix Approach |
|
|
94
|
+
| ------------- | ---------------- | ------------ |
|
|
95
|
+
| race-condition | `type/flaky-test`, `component/e2e` | Add explicit waits; fix async ordering |
|
|
96
|
+
| shared-state | `type/flaky-test`, `component/unit` | Isolate state; use fresh fixtures |
|
|
97
|
+
| time-dependency | `type/flaky-test` | Mock time; use deterministic delays |
|
|
98
|
+
| external-dependency | `type/flaky-test`, `component/integration` | Mock external service; retry with backoff |
|
|
99
|
+
|
|
100
|
+
### Sub-issues
|
|
101
|
+
|
|
102
|
+
For complex flaky tests, create sub-tasks:
|
|
103
|
+
|
|
104
|
+
- #201: Investigate flaky login test
|
|
105
|
+
- #202: Add explicit wait for redirect (child)
|
|
106
|
+
- #203: Verify stability in CI (child)
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 4. Spec Drift → Update Workflow
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
[Spec Auditor] → [Spec Drift Issue] → [Update Task] → [PR] → [Verify]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Flow
|
|
117
|
+
|
|
118
|
+
1. **qa-spec-auditor** finds mismatch (requirements vs implementation vs tests)
|
|
119
|
+
2. Create `type/documentation` or `spec-drift` issue:
|
|
120
|
+
- What is drifted (requirement, spec, API contract)
|
|
121
|
+
- Current vs expected state
|
|
122
|
+
- Affected tests
|
|
123
|
+
3. Create update task: update spec, or fix implementation, or update tests
|
|
124
|
+
4. PR; verify spec-auditor passes
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 5. Bulk Operations Pattern
|
|
129
|
+
|
|
130
|
+
### Input Sources
|
|
131
|
+
|
|
132
|
+
| Source | Output |
|
|
133
|
+
| ------ | ------ |
|
|
134
|
+
| qa-coverage-analyzer | Batch of coverage gap issues |
|
|
135
|
+
| qa-spec-auditor | Batch of spec drift issues |
|
|
136
|
+
| qa-flaky-detector | Batch of flaky test issues |
|
|
137
|
+
| qa-changelog-analyzer | Batch of "recommended tests to run" tasks |
|
|
138
|
+
|
|
139
|
+
### Bulk Create Rules
|
|
140
|
+
|
|
141
|
+
1. **Deduplicate**: Search existing issues before creating; skip if similar exists
|
|
142
|
+
2. **Batch size**: Create in batches of 10–20 to avoid rate limits
|
|
143
|
+
3. **Milestone**: Assign same milestone to batch when provided
|
|
144
|
+
4. **Labels**: Apply consistent labels per batch type
|
|
145
|
+
5. **Throttle**: Add small delay between API calls if needed
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 6. Search and Deduplication
|
|
150
|
+
|
|
151
|
+
### Before Creating Any Issue
|
|
152
|
+
|
|
153
|
+
1. **Search** via GitHub MCP:
|
|
154
|
+
- By title keywords (normalize: lowercase, remove punctuation)
|
|
155
|
+
- By component + type
|
|
156
|
+
- By error message snippet (for bugs)
|
|
157
|
+
- By file:line (for coverage gaps)
|
|
158
|
+
2. **Compare**:
|
|
159
|
+
- Same root cause? → Comment on existing; do not create
|
|
160
|
+
- Related but distinct? → Create with "Related to #N"
|
|
161
|
+
- Truly new? → Create
|
|
162
|
+
3. **Report**: If duplicate found, inform user and link to existing issue
|
|
163
|
+
|
|
164
|
+
### Search Query Examples
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
# Bugs: similar title + component
|
|
168
|
+
is:open label:type/bug "login" label:component/auth
|
|
169
|
+
|
|
170
|
+
# Coverage: same file
|
|
171
|
+
is:open label:type/test-coverage-gap "AuthService.ts"
|
|
172
|
+
|
|
173
|
+
# Flaky: same test path
|
|
174
|
+
is:open label:type/flaky-test "login.spec.ts"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Integration Summary
|
|
180
|
+
|
|
181
|
+
| Skill | Consumes | Produces |
|
|
182
|
+
| ----- | -------- | -------- |
|
|
183
|
+
| qa-github-issues-enhanced | Coverage gaps, spec drift, flaky reports, bug descriptions | Labeled issues, milestones, linked tasks |
|
|
184
|
+
| qa-bug-ticket-creator | Test failures | Bug issues (uses this skill's labels/templates) |
|
|
185
|
+
| qa-task-creator | Bug issues, coverage gaps | Fix/verification tasks |
|
|
186
|
+
| qa-coverage-analyzer | Code, coverage reports | Coverage gap list |
|
|
187
|
+
| qa-spec-auditor | Requirements, implementation, tests | Spec drift list |
|
|
188
|
+
| qa-flaky-detector | CI history, test results | Flaky test list |
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-httpx-writer
|
|
3
|
+
description: Generate httpx/requests API tests for Python with async support, session management, and schema validation using pytest.
|
|
4
|
+
output_dir: tests/api
|
|
5
|
+
dependencies:
|
|
6
|
+
recommended:
|
|
7
|
+
- qa-api-contract-curator
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# QA httpx Writer
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Write Python API tests using httpx (or requests) from test case specifications and API contracts. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer) and OpenAPI contracts (from qa-api-contract-curator) into executable pytest API tests with async support, session management, response schema validation, and authentication handling.
|
|
15
|
+
|
|
16
|
+
## Trigger Phrases
|
|
17
|
+
|
|
18
|
+
- "Write httpx tests for [API/endpoint]"
|
|
19
|
+
- "Generate Python API tests from OpenAPI contract"
|
|
20
|
+
- "Create httpx API tests for [resource]"
|
|
21
|
+
- "Add httpx tests with Pydantic validation"
|
|
22
|
+
- "API tests with httpx.AsyncClient"
|
|
23
|
+
- "Python API tests from test cases"
|
|
24
|
+
- "httpx tests with auth and retry logic"
|
|
25
|
+
- "requests API tests for [endpoint]"
|
|
26
|
+
|
|
27
|
+
## Key Features
|
|
28
|
+
|
|
29
|
+
| Feature | Description |
|
|
30
|
+
| ------- | ----------- |
|
|
31
|
+
| **Async support** | `httpx.AsyncClient` for async tests; `httpx.Client` for sync |
|
|
32
|
+
| **Session management** | Connection pooling, cookie persistence, header reuse |
|
|
33
|
+
| **Response validation** | Pydantic models, JSON Schema for contract compliance |
|
|
34
|
+
| **Authentication** | Bearer token, API key, OAuth2, Basic Auth, cookies |
|
|
35
|
+
| **Retry logic** | Configurable retries for transient failures |
|
|
36
|
+
| **Context managers** | `with httpx.Client()` / `async with httpx.AsyncClient()` |
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
1. **Read test cases + API contract** — From qa-testcase-from-docs, qa-manual-test-designer, or qa-api-contract-curator (OpenAPI)
|
|
41
|
+
2. **Generate pytest API test files** — Produce `test_{resource}_api.py` with test functions per endpoint
|
|
42
|
+
3. **Add fixtures** — `conftest.py` with `base_url`, client fixtures (sync/async)
|
|
43
|
+
4. **Validate responses** — Status codes, headers, JSON body; Pydantic/JSON Schema validation
|
|
44
|
+
|
|
45
|
+
## Context7 MCP
|
|
46
|
+
|
|
47
|
+
Use **Context7 MCP** for httpx documentation when:
|
|
48
|
+
- API signatures or async/sync usage are uncertain
|
|
49
|
+
- Transport options, timeout, or retry configuration need verification
|
|
50
|
+
- Response streaming or file upload APIs require clarification
|
|
51
|
+
|
|
52
|
+
## Key Patterns
|
|
53
|
+
|
|
54
|
+
| Pattern | Usage |
|
|
55
|
+
| ------- | ----- |
|
|
56
|
+
| `httpx.Client()` | Sync client; use as context manager |
|
|
57
|
+
| `httpx.AsyncClient()` | Async client; use with `async with` |
|
|
58
|
+
| `response.status_code` | Assert HTTP status |
|
|
59
|
+
| `response.json()` | Parse JSON body |
|
|
60
|
+
| `response.headers` | Access response headers |
|
|
61
|
+
| `client.get(url)` / `client.post(url)` | HTTP methods |
|
|
62
|
+
| `client.get(url, headers=...)` | Custom headers (auth, etc.) |
|
|
63
|
+
| Pydantic validation | `Model.model_validate(response.json())` |
|
|
64
|
+
| pytest fixtures | `base_url`, `client`, `async_client` in conftest |
|
|
65
|
+
|
|
66
|
+
See `references/patterns.md` for CRUD, auth, file upload, streaming, async.
|
|
67
|
+
|
|
68
|
+
## Test Structure
|
|
69
|
+
|
|
70
|
+
- **conftest.py** — `base_url`, `client` (sync), `async_client` (async) fixtures
|
|
71
|
+
- **test_{resource}_api.py** — One file per resource/endpoint group
|
|
72
|
+
- **describe/it** equivalent — `class TestUsersAPI:` with `def test_*` methods
|
|
73
|
+
|
|
74
|
+
## Auth Patterns
|
|
75
|
+
|
|
76
|
+
| Type | Usage |
|
|
77
|
+
| ---- | ----- |
|
|
78
|
+
| **Bearer token** | `headers={"Authorization": f"Bearer {token}"}` |
|
|
79
|
+
| **API key** | `headers={"X-API-Key": api_key}` or `params={"api_key": key}` |
|
|
80
|
+
| **OAuth2** | `httpx.OAuth2Client` or manual token in headers |
|
|
81
|
+
| **Basic Auth** | `auth=httpx.BasicAuth(user, password)` |
|
|
82
|
+
| **Cookies** | Session cookies via `client.cookies` or `headers={"Cookie": ...}` |
|
|
83
|
+
|
|
84
|
+
## File Naming
|
|
85
|
+
|
|
86
|
+
- `test_{resource}_api.py` — e.g., `test_users_api.py`, `test_products_api.py`
|
|
87
|
+
- Place in `tests/` or `tests/api/` per project convention
|
|
88
|
+
|
|
89
|
+
## Scope
|
|
90
|
+
|
|
91
|
+
**Can do (autonomous):**
|
|
92
|
+
- Generate httpx/requests API tests from test cases and OpenAPI contracts
|
|
93
|
+
- Add conftest.py with base_url, client fixtures (sync/async)
|
|
94
|
+
- Use Pydantic or JSON Schema for response validation
|
|
95
|
+
- Implement auth patterns (Bearer, API key, Basic, cookies)
|
|
96
|
+
- Add retry logic, timeout configuration
|
|
97
|
+
- Call qa-api-contract-curator for contract when needed
|
|
98
|
+
- Use Context7 MCP for httpx docs
|
|
99
|
+
|
|
100
|
+
**Cannot do (requires confirmation):**
|
|
101
|
+
- Change production API implementation
|
|
102
|
+
- Add dependencies not in requirements.txt/pyproject.toml
|
|
103
|
+
- Override project test config without approval
|
|
104
|
+
|
|
105
|
+
**Will not do (out of scope):**
|
|
106
|
+
- Execute tests (user runs `pytest`)
|
|
107
|
+
- Write E2E browser tests (use qa-playwright-ts-writer)
|
|
108
|
+
- Modify CI/CD pipelines
|
|
109
|
+
|
|
110
|
+
## References
|
|
111
|
+
|
|
112
|
+
- `references/patterns.md` — CRUD, auth, file upload, streaming, async
|
|
113
|
+
- `references/assertions.md` — Status codes, JSON body, headers, Pydantic/JSON Schema validation
|
|
114
|
+
- `references/config.md` — conftest.py, fixtures, environment config, base URL
|
|
115
|
+
- `references/best-practices.md` — Async vs sync, session reuse, schema validation, test isolation
|
|
116
|
+
|
|
117
|
+
## Quality Checklist
|
|
118
|
+
|
|
119
|
+
- [ ] Tests match test case steps and expected results
|
|
120
|
+
- [ ] Each endpoint has success and error scenarios (validation, 401, 404)
|
|
121
|
+
- [ ] Auth setup is correct and isolated per test
|
|
122
|
+
- [ ] No hardcoded secrets; use env vars or fixtures
|
|
123
|
+
- [ ] Response assertions are specific (status, body shape, headers)
|
|
124
|
+
- [ ] File naming follows `test_{resource}_api.py`
|
|
125
|
+
- [ ] Client fixtures use context managers; proper teardown
|
|
126
|
+
- [ ] Schema validation used where contract specifies response shape
|
|
127
|
+
|
|
128
|
+
## Troubleshooting
|
|
129
|
+
|
|
130
|
+
| Symptom | Likely Cause | Fix |
|
|
131
|
+
| ------- | ------------ | --- |
|
|
132
|
+
| Connection refused | Wrong base_url or server not running | Verify `base_url` in conftest; ensure API is up |
|
|
133
|
+
| Tests pass individually, fail together | Shared client state or connection pool | Use function-scoped client fixture; avoid session reuse across tests |
|
|
134
|
+
| `response.json()` fails | Non-JSON response (204, HTML error) | Check `response.status_code`; use `response.text` for non-JSON |
|
|
135
|
+
| Async tests fail | Missing pytest-asyncio | Add `@pytest.mark.asyncio`; install pytest-asyncio; set `asyncio_mode = "auto"` |
|
|
136
|
+
| Auth not working | Token expired or wrong header | Check `Authorization` format; ensure token in scope |
|
|
137
|
+
| Pydantic validation error | Response shape differs from model | Align model with API contract; use `model_validate` with `strict=False` if needed |
|
|
138
|
+
| Timeout errors | Slow API or network | Increase `timeout` in client; add retry for transient failures |
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# httpx Response Validation
|
|
2
|
+
|
|
3
|
+
## Status Codes
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
response = client.get(f"{base_url}/users")
|
|
7
|
+
assert response.status_code == 200
|
|
8
|
+
|
|
9
|
+
response = client.post(f"{base_url}/users", json={...})
|
|
10
|
+
assert response.status_code == 201
|
|
11
|
+
|
|
12
|
+
response = client.delete(f"{base_url}/users/1")
|
|
13
|
+
assert response.status_code == 204
|
|
14
|
+
|
|
15
|
+
response = client.get(f"{base_url}/users/99999")
|
|
16
|
+
assert response.status_code == 404
|
|
17
|
+
|
|
18
|
+
response = client.get(f"{base_url}/users") # No auth
|
|
19
|
+
assert response.status_code == 401
|
|
20
|
+
|
|
21
|
+
response = client.post(f"{base_url}/users", json={"email": "invalid"})
|
|
22
|
+
assert response.status_code == 400
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Code | Typical Use |
|
|
26
|
+
| ---- | ----------- |
|
|
27
|
+
| 200 | OK — GET, PUT, PATCH success |
|
|
28
|
+
| 201 | Created — POST success |
|
|
29
|
+
| 204 | No Content — DELETE success |
|
|
30
|
+
| 400 | Bad Request — validation error |
|
|
31
|
+
| 401 | Unauthorized — missing/invalid auth |
|
|
32
|
+
| 403 | Forbidden — insufficient permissions |
|
|
33
|
+
| 404 | Not Found — resource missing |
|
|
34
|
+
| 409 | Conflict — duplicate, constraint violation |
|
|
35
|
+
| 422 | Unprocessable Entity — semantic validation |
|
|
36
|
+
| 500 | Internal Server Error |
|
|
37
|
+
|
|
38
|
+
## JSON Body Assertions
|
|
39
|
+
|
|
40
|
+
### Basic Checks
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
data = response.json()
|
|
44
|
+
assert "users" in data
|
|
45
|
+
assert isinstance(data["users"], list)
|
|
46
|
+
assert len(data["users"]) > 0
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Partial Match (Dynamic Fields)
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
# Use dict subset for id, createdAt, etc.
|
|
53
|
+
user = response.json()
|
|
54
|
+
assert user["email"] == "test@example.com"
|
|
55
|
+
assert "id" in user
|
|
56
|
+
assert isinstance(user["id"], int)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Nested Structure
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
data = response.json()
|
|
63
|
+
assert "data" in data
|
|
64
|
+
assert "items" in data["data"]
|
|
65
|
+
assert all("id" in item for item in data["data"]["items"])
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Header Assertions
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
assert "application/json" in response.headers.get("content-type", "")
|
|
72
|
+
assert "x-request-id" in response.headers
|
|
73
|
+
assert response.headers["cache-control"] == "no-cache"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Schema Validation with Pydantic
|
|
77
|
+
|
|
78
|
+
### Define Model
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from pydantic import BaseModel
|
|
82
|
+
|
|
83
|
+
class UserResponse(BaseModel):
|
|
84
|
+
id: int
|
|
85
|
+
email: str
|
|
86
|
+
name: str | None = None
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Validate Response
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
def test_user_response_schema(client, base_url, auth_headers):
|
|
93
|
+
response = client.get(f"{base_url}/users/1", headers=auth_headers)
|
|
94
|
+
assert response.status_code == 200
|
|
95
|
+
user = UserResponse.model_validate(response.json())
|
|
96
|
+
assert user.id == 1
|
|
97
|
+
assert "@" in user.email
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### List Response
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
class UserListResponse(BaseModel):
|
|
104
|
+
users: list[UserResponse]
|
|
105
|
+
total: int
|
|
106
|
+
|
|
107
|
+
def test_user_list_schema(client, base_url, auth_headers):
|
|
108
|
+
response = client.get(f"{base_url}/users", headers=auth_headers)
|
|
109
|
+
assert response.status_code == 200
|
|
110
|
+
data = UserListResponse.model_validate(response.json())
|
|
111
|
+
assert isinstance(data.users, list)
|
|
112
|
+
assert data.total >= 0
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### ValidationError Handling
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from pydantic import ValidationError
|
|
119
|
+
|
|
120
|
+
def test_invalid_response_raises(client, base_url):
|
|
121
|
+
response = client.get(f"{base_url}/broken")
|
|
122
|
+
assert response.status_code == 200
|
|
123
|
+
with pytest.raises(ValidationError):
|
|
124
|
+
UserResponse.model_validate(response.json())
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## JSON Schema Validation
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
import jsonschema
|
|
131
|
+
|
|
132
|
+
USER_SCHEMA = {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"required": ["id", "email"],
|
|
135
|
+
"properties": {
|
|
136
|
+
"id": {"type": "integer"},
|
|
137
|
+
"email": {"type": "string", "format": "email"},
|
|
138
|
+
"name": {"type": "string"},
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
def test_user_json_schema(client, base_url, auth_headers):
|
|
143
|
+
response = client.get(f"{base_url}/users/1", headers=auth_headers)
|
|
144
|
+
assert response.status_code == 200
|
|
145
|
+
jsonschema.validate(response.json(), USER_SCHEMA)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Content-Type Check
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
def test_json_response(client, base_url):
|
|
152
|
+
response = client.get(f"{base_url}/users")
|
|
153
|
+
assert response.status_code == 200
|
|
154
|
+
content_type = response.headers.get("content-type", "")
|
|
155
|
+
assert "application/json" in content_type
|
|
156
|
+
# Only then parse JSON
|
|
157
|
+
data = response.json()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Empty Response (204)
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
def test_delete_returns_empty(client, base_url, auth_headers):
|
|
164
|
+
response = client.delete(f"{base_url}/users/1", headers=auth_headers)
|
|
165
|
+
assert response.status_code == 204
|
|
166
|
+
assert response.content == b""
|
|
167
|
+
# Do not call response.json() on 204
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Error Response Structure
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
def test_validation_error_structure(client, base_url):
|
|
174
|
+
response = client.post(f"{base_url}/users", json={})
|
|
175
|
+
assert response.status_code == 400
|
|
176
|
+
data = response.json()
|
|
177
|
+
assert "errors" in data or "message" in data
|
|
178
|
+
if "errors" in data:
|
|
179
|
+
assert isinstance(data["errors"], list)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Parametrized Assertions
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
@pytest.mark.parametrize("status,expected", [
|
|
186
|
+
(200, True),
|
|
187
|
+
(201, True),
|
|
188
|
+
(400, False),
|
|
189
|
+
(404, False),
|
|
190
|
+
])
|
|
191
|
+
def test_status_codes(client, base_url, status, expected):
|
|
192
|
+
# Adjust endpoint to trigger each status
|
|
193
|
+
response = client.get(f"{base_url}/users")
|
|
194
|
+
assert (response.status_code == status) == expected
|
|
195
|
+
```
|