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,84 @@
|
|
|
1
|
+
# Scheduler Trigger Rules and Automation Patterns
|
|
2
|
+
|
|
3
|
+
Rules for when to trigger pipelines and what actions to take.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## After Merge
|
|
8
|
+
|
|
9
|
+
**Trigger:** PR merged to main/master (or configured branch)
|
|
10
|
+
|
|
11
|
+
**Actions:**
|
|
12
|
+
1. Run smoke/regression suite
|
|
13
|
+
2. Generate test report
|
|
14
|
+
3. If failures: invoke qa-bug-ticket-creator for each failure
|
|
15
|
+
|
|
16
|
+
**Skills invoked:** [test execution] → test-reporter → bug-ticket-creator (conditional)
|
|
17
|
+
|
|
18
|
+
**Automation pattern:**
|
|
19
|
+
- CI hook (GitHub Actions, etc.) runs tests post-merge
|
|
20
|
+
- Orchestrator consumes results, generates report
|
|
21
|
+
- On failure: create bug tickets with reproduction steps
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Before Release
|
|
26
|
+
|
|
27
|
+
**Trigger:** Release candidate tagged or release branch cut
|
|
28
|
+
|
|
29
|
+
**Actions:**
|
|
30
|
+
1. Run full regression
|
|
31
|
+
2. Generate completion report
|
|
32
|
+
3. Run risk-analyzer for release scope
|
|
33
|
+
4. Output: release readiness summary
|
|
34
|
+
|
|
35
|
+
**Skills invoked:** [test execution] → test-reporter → risk-analyzer
|
|
36
|
+
|
|
37
|
+
**Output:** Completion report + risk summary for sign-off
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## After Requirement Change
|
|
42
|
+
|
|
43
|
+
**Trigger:** Requirements/spec document updated
|
|
44
|
+
|
|
45
|
+
**Actions:**
|
|
46
|
+
1. Impact analysis (affected test cases, specs)
|
|
47
|
+
2. Update RTM (Requirements Traceability Matrix)
|
|
48
|
+
3. Flag tests/specs needing update
|
|
49
|
+
|
|
50
|
+
**Skills invoked:** spec-auditor (or requirements diff) → coverage-analyzer (RTM) → task-creator (for update tasks)
|
|
51
|
+
|
|
52
|
+
**Output:** Impact report + tasks for spec/test updates
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Scheduler Integration
|
|
57
|
+
|
|
58
|
+
| Trigger | CI Event | Orchestrator Response |
|
|
59
|
+
| ------- | -------- | --------------------- |
|
|
60
|
+
| After merge | `push` to main | Smoke/regression → report → bug if fail |
|
|
61
|
+
| Before release | `release` tag / workflow | Full regression → completion report + risk |
|
|
62
|
+
| Requirement change | Manual / file watch | Impact analysis → RTM update |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
Scheduler rules can be configured via:
|
|
69
|
+
- `.cursor/rules/` — project-specific overrides
|
|
70
|
+
- Memory MCP — persisted trigger state
|
|
71
|
+
- Environment — branch names, report paths
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Automation Patterns
|
|
76
|
+
|
|
77
|
+
### Pattern 1: Fail-fast
|
|
78
|
+
On first failure in smoke, stop and create bug. Do not continue full suite.
|
|
79
|
+
|
|
80
|
+
### Pattern 2: Full report then bugs
|
|
81
|
+
Complete full run, generate report, then create bugs for all failures.
|
|
82
|
+
|
|
83
|
+
### Pattern 3: Risk-gated
|
|
84
|
+
Before release: if risk-analyzer flags high risk, require additional tests before sign-off.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-pact-writer
|
|
3
|
+
description: Generate consumer-driven contract tests using Pact for JavaScript and Python to verify microservice API compatibility between consumer and provider.
|
|
4
|
+
output_dir: tests/contracts
|
|
5
|
+
dependencies:
|
|
6
|
+
recommended:
|
|
7
|
+
- qa-api-contract-curator
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# QA Pact Writer
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Write consumer-driven contract tests for microservice API compatibility. Transform API contracts (from qa-api-contract-curator) into Pact consumer tests and provider verification tests. Ensure consumer and provider services remain compatible without brittle end-to-end integration tests.
|
|
15
|
+
|
|
16
|
+
## Key Concepts
|
|
17
|
+
|
|
18
|
+
| Concept | Description |
|
|
19
|
+
| ------- | ----------- |
|
|
20
|
+
| **Consumer** | Service that makes requests (e.g., frontend, API gateway, another microservice) |
|
|
21
|
+
| **Provider** | Service that serves requests (e.g., REST API, backend service) |
|
|
22
|
+
| **Pact** | Contract/agreement describing expected request/response between consumer and provider |
|
|
23
|
+
| **Pact Broker** | Central repository for publishing, versioning, and sharing pacts |
|
|
24
|
+
| **Consumer-driven** | Consumer defines expectations; provider verifies it meets them |
|
|
25
|
+
|
|
26
|
+
## Languages & Libraries
|
|
27
|
+
|
|
28
|
+
| Language | Library | Notes |
|
|
29
|
+
| -------- | ------- | ----- |
|
|
30
|
+
| **JavaScript/TypeScript** | `@pact-foundation/pact` | PactV4 (default), HTTP + async/sync messages |
|
|
31
|
+
| **Python** | `pact-python` | pytest integration, functional state handlers (v2.3+) |
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
|
|
35
|
+
1. **Read API contract** — From qa-api-contract-curator (OpenAPI) or existing endpoint specs
|
|
36
|
+
2. **Write consumer tests** — Define interactions (given state, request, expected response); run tests to generate pact JSON
|
|
37
|
+
3. **Generate pact files** — Pact JSON written to `pacts/` or published to broker
|
|
38
|
+
4. **Write provider verification** — Verify pact against real provider; set up provider states
|
|
39
|
+
5. **Publish to broker** — Publish pacts; run can-i-deploy checks; configure webhooks
|
|
40
|
+
|
|
41
|
+
## Consumer Side
|
|
42
|
+
|
|
43
|
+
- **Define interactions** — `given` (provider state), `uponReceiving` (scenario name), request (method, path, headers, body), expected response (status, headers, body)
|
|
44
|
+
- **Run tests** — Consumer tests hit Pact mock server; generate pact JSON on success
|
|
45
|
+
- **Matchers** — `like`, `eachLike`, `term`, `regex` for flexible matching
|
|
46
|
+
|
|
47
|
+
## Provider Side
|
|
48
|
+
|
|
49
|
+
- **Verify pact** — Replay interactions from pact against real provider
|
|
50
|
+
- **Provider states** — Set up data/state before each interaction (e.g., "user exists", "order is pending")
|
|
51
|
+
- **State handlers** — Functions or endpoints that prepare provider for each `given` state
|
|
52
|
+
|
|
53
|
+
## Pact Broker
|
|
54
|
+
|
|
55
|
+
- **Publish pacts** — Consumer publishes after tests pass
|
|
56
|
+
- **can-i-deploy** — Check if consumer/provider versions are compatible before deployment
|
|
57
|
+
- **Webhooks** — Trigger provider verification when new pacts are published
|
|
58
|
+
|
|
59
|
+
## Key Patterns
|
|
60
|
+
|
|
61
|
+
| Pattern | JavaScript | Python |
|
|
62
|
+
| ------- | ---------- | ------ |
|
|
63
|
+
| **Consumer setup** | `new PactV4()` / `new Pact()` | `pact.Consumer(...).has_pact_with(...)` |
|
|
64
|
+
| **Provider verification** | `Verifier.verifyProvider()` | `Verifier(provider=...).verify_pacts()` |
|
|
65
|
+
| **Provider states** | `given()` in interaction | `state_handler` / `set_state` |
|
|
66
|
+
| **Matchers** | `like()`, `eachLike()`, `term()` | `Like`, `EachLike`, `Term` |
|
|
67
|
+
| **Pending pacts** | `pending: true` | `pending: True` |
|
|
68
|
+
| **WIP pacts** | `wip: true` | `wip: True` |
|
|
69
|
+
|
|
70
|
+
See `references/patterns.md` for consumer tests, provider verification, matchers, provider states.
|
|
71
|
+
|
|
72
|
+
## Output
|
|
73
|
+
|
|
74
|
+
- **Consumer tests** — Jest/Vitest (JS) or pytest (Python) files that generate pacts
|
|
75
|
+
- **Provider verification tests** — Scripts or config that verify provider against pacts
|
|
76
|
+
- **Pact JSON contracts** — `{consumer}-{provider}.json` in `pacts/` or broker
|
|
77
|
+
|
|
78
|
+
## Feeds Into / From
|
|
79
|
+
|
|
80
|
+
- **qa-api-contract-curator** — Use OpenAPI as input for consumer expectations
|
|
81
|
+
- **qa-supertest-writer** — Consumer tests may use Supertest-like patterns for HTTP
|
|
82
|
+
- **qa-httpx-writer** — Python consumer tests may use httpx for HTTP calls
|
|
83
|
+
|
|
84
|
+
## Scope
|
|
85
|
+
|
|
86
|
+
**Can do (autonomous):**
|
|
87
|
+
- Generate consumer tests from API contract (OpenAPI or description)
|
|
88
|
+
- Generate provider verification setup from pact files
|
|
89
|
+
- Define provider states and state handlers
|
|
90
|
+
- Use matchers (like, eachLike, term, regex)
|
|
91
|
+
- Configure Pact Broker publish and verification
|
|
92
|
+
- Add pending/WIP pacts for in-progress work
|
|
93
|
+
- Call qa-api-contract-curator for contract when needed
|
|
94
|
+
|
|
95
|
+
**Cannot do (requires confirmation):**
|
|
96
|
+
- Change production API implementation
|
|
97
|
+
- Add dependencies not in package.json / requirements.txt
|
|
98
|
+
- Override project test config without approval
|
|
99
|
+
- Deploy or modify Pact Broker infrastructure
|
|
100
|
+
|
|
101
|
+
**Will not do (out of scope):**
|
|
102
|
+
- Execute tests (user runs `npm test` or `pytest`)
|
|
103
|
+
- Set up or host Pact Broker (use Pactflow, self-hosted broker)
|
|
104
|
+
- Write E2E browser tests (use qa-playwright-ts-writer)
|
|
105
|
+
|
|
106
|
+
## Quality Checklist
|
|
107
|
+
|
|
108
|
+
Before delivering Pact tests:
|
|
109
|
+
|
|
110
|
+
- [ ] Consumer tests define all interactions from API contract
|
|
111
|
+
- [ ] Provider states match consumer `given` clauses
|
|
112
|
+
- [ ] Matchers used for dynamic fields (IDs, timestamps, etc.)
|
|
113
|
+
- [ ] No hardcoded secrets; use env vars for broker URL, tokens
|
|
114
|
+
- [ ] Pact file path or broker config is correct
|
|
115
|
+
- [ ] Provider verification runs against real provider (or documented stub)
|
|
116
|
+
- [ ] Pending/WIP pacts have clear comments on completion criteria
|
|
117
|
+
|
|
118
|
+
## Troubleshooting
|
|
119
|
+
|
|
120
|
+
| Symptom | Likely Cause | Fix |
|
|
121
|
+
| ------- | ------------ | --- |
|
|
122
|
+
| Pact mock server port conflict | Port already in use | Change `port` in Pact config; use random port |
|
|
123
|
+
| Provider verification fails | State handler not matching `given` | Ensure state handler name matches consumer `given` exactly |
|
|
124
|
+
| Pact not published to broker | Wrong URL, auth, or version | Verify `PACT_BROKER_BASE_URL`, `PACT_BROKER_TOKEN`; check version in publish |
|
|
125
|
+
| Matcher mismatch on provider | Provider returns different shape | Align consumer matchers with provider response; or fix provider |
|
|
126
|
+
| Consumer test passes, pact empty | Pact not written before teardown | Ensure `executeTest()` / `verify()` completes; check output path |
|
|
127
|
+
| Python state handler not called | Wrong state name or handler signature | Match `given` string; use `state_handler` with correct params (v2.3+) |
|
|
128
|
+
|
|
129
|
+
## References
|
|
130
|
+
|
|
131
|
+
- `references/patterns.md` — Consumer tests, provider verification, matchers, provider states
|
|
132
|
+
- `references/config.md` — Pact Broker setup, CI integration, can-i-deploy
|
|
133
|
+
- `references/best-practices.md` — Consumer-driven workflow, versioning, broker management
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Contract Testing Best Practices
|
|
2
|
+
|
|
3
|
+
## Consumer-Driven Workflow
|
|
4
|
+
|
|
5
|
+
1. **Consumer defines expectations** — Consumer team writes tests based on what they need from the API, not what the provider thinks it offers.
|
|
6
|
+
2. **Provider verifies** — Provider team runs verification to ensure they meet consumer expectations.
|
|
7
|
+
3. **Negotiate changes** — When provider cannot meet expectations, teams discuss; consumer may relax expectations or provider may implement.
|
|
8
|
+
|
|
9
|
+
### Benefits
|
|
10
|
+
|
|
11
|
+
- Prevents over-specification (provider only implements what consumers need)
|
|
12
|
+
- Catches breaking changes before deployment
|
|
13
|
+
- Reduces need for expensive, brittle E2E tests
|
|
14
|
+
- Enables independent deployment of services
|
|
15
|
+
|
|
16
|
+
## Versioning
|
|
17
|
+
|
|
18
|
+
### Consumer Version
|
|
19
|
+
|
|
20
|
+
- Use deterministic versions: git SHA, semver from package.json
|
|
21
|
+
- Publish on every successful consumer test run
|
|
22
|
+
- Tag with branch for branch-based verification
|
|
23
|
+
|
|
24
|
+
### Provider Version
|
|
25
|
+
|
|
26
|
+
- Publish verification results with provider version
|
|
27
|
+
- Link verification to provider deployment pipeline
|
|
28
|
+
- Use same versioning scheme as consumer
|
|
29
|
+
|
|
30
|
+
### Pact Contract Versioning
|
|
31
|
+
|
|
32
|
+
- Pact spec version (v3, v4) is separate from application versions
|
|
33
|
+
- Upgrade Pact library when adding new features (e.g., PactV4 for async)
|
|
34
|
+
|
|
35
|
+
## Broker Management
|
|
36
|
+
|
|
37
|
+
### Organizing Pacts
|
|
38
|
+
|
|
39
|
+
- One pact per consumer-provider pair
|
|
40
|
+
- Use consistent naming: `{ConsumerService}-{ProviderService}.json`
|
|
41
|
+
- Tag with environments after successful verification
|
|
42
|
+
|
|
43
|
+
### Webhooks
|
|
44
|
+
|
|
45
|
+
- Configure webhook: when consumer publishes pact → trigger provider verification
|
|
46
|
+
- Reduces manual coordination between teams
|
|
47
|
+
- Provider verification can run in provider's CI or a shared contract verification pipeline
|
|
48
|
+
|
|
49
|
+
### Retention
|
|
50
|
+
|
|
51
|
+
- Keep pact history for auditing and debugging
|
|
52
|
+
- Consider retention policy for old versions (broker-dependent)
|
|
53
|
+
- Archive or delete pacts for deprecated consumer-provider pairs
|
|
54
|
+
|
|
55
|
+
## Test Design
|
|
56
|
+
|
|
57
|
+
### Consumer Tests
|
|
58
|
+
|
|
59
|
+
- **One interaction per test** — Isolate scenarios; easier to debug
|
|
60
|
+
- **Minimal expectations** — Assert only what the consumer uses
|
|
61
|
+
- **Use matchers** — Avoid exact matches for IDs, timestamps, dynamic data
|
|
62
|
+
- **Descriptive scenario names** — `uponReceiving` should describe the scenario clearly
|
|
63
|
+
|
|
64
|
+
### Provider States
|
|
65
|
+
|
|
66
|
+
- **Idempotent** — State setup should be repeatable
|
|
67
|
+
- **Isolated** — No shared state between interactions
|
|
68
|
+
- **Fast** — Prefer in-memory or test DB; avoid slow external calls
|
|
69
|
+
- **Parameterized** — Use params for reusable states (e.g., `userId`)
|
|
70
|
+
|
|
71
|
+
### Provider Verification
|
|
72
|
+
|
|
73
|
+
- **Run against real provider** — Use actual app, not mocks (except for provider's own dependencies)
|
|
74
|
+
- **Test DB or fixtures** — Provider states seed data; use separate test DB
|
|
75
|
+
- **Parallel verification** — Verify multiple pacts in parallel when possible
|
|
76
|
+
|
|
77
|
+
## Pending and WIP Pacts
|
|
78
|
+
|
|
79
|
+
### Pending Pacts
|
|
80
|
+
|
|
81
|
+
- New consumer expectations not yet implemented by provider
|
|
82
|
+
- Mark as `pending: true` so provider verification does not fail
|
|
83
|
+
- Remove pending when provider implements and verification passes
|
|
84
|
+
|
|
85
|
+
### WIP (Work in Progress) Pacts
|
|
86
|
+
|
|
87
|
+
- In-progress consumer work; pact may change frequently
|
|
88
|
+
- Mark as `wip: true` to exclude from strict verification
|
|
89
|
+
- Use `consumerVersionSelectors` with `wip: true` to include in verification without failing
|
|
90
|
+
|
|
91
|
+
## Anti-Patterns to Avoid
|
|
92
|
+
|
|
93
|
+
| Anti-Pattern | Problem | Better Approach |
|
|
94
|
+
| ------------ | ------- | --------------- |
|
|
95
|
+
| Copy-pasting provider response | Over-specification; brittle | Use matchers; assert only needed fields |
|
|
96
|
+
| Skipping provider states | Flaky verification | Always define state handlers for `given` |
|
|
97
|
+
| Verifying against mocks | False confidence | Verify against real provider |
|
|
98
|
+
| One giant interaction | Hard to debug | One interaction per scenario |
|
|
99
|
+
| Hardcoded broker URL/token | Security risk | Use env vars |
|
|
100
|
+
| Ignoring pending pacts | Blocked deployments | Use pending; track implementation |
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Pact Configuration
|
|
2
|
+
|
|
3
|
+
## Pact Broker Setup
|
|
4
|
+
|
|
5
|
+
### Environment Variables
|
|
6
|
+
|
|
7
|
+
| Variable | Description | Required |
|
|
8
|
+
| -------- | ----------- | -------- |
|
|
9
|
+
| `PACT_BROKER_BASE_URL` | Broker URL (e.g., `https://broker.pactflow.io`) | For publish/verify from broker |
|
|
10
|
+
| `PACT_BROKER_TOKEN` | API token for authentication | When broker requires auth |
|
|
11
|
+
| `PACT_BROKER_USERNAME` | Basic auth username | Alternative to token |
|
|
12
|
+
| `PACT_BROKER_PASSWORD` | Basic auth password | Alternative to token |
|
|
13
|
+
|
|
14
|
+
### Publish Pact (Consumer)
|
|
15
|
+
|
|
16
|
+
**JavaScript:**
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"scripts": {
|
|
20
|
+
"pact:publish": "pact-broker publish pacts/ --consumer-app-version=$npm_package_version --tag=main"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Python:**
|
|
26
|
+
```bash
|
|
27
|
+
pact-broker publish pacts/ --consumer-app-version=1.2.3 --tag=main
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Verify from Broker (Provider)
|
|
31
|
+
|
|
32
|
+
**JavaScript:**
|
|
33
|
+
```typescript
|
|
34
|
+
await new Verifier({
|
|
35
|
+
provider: 'UserService',
|
|
36
|
+
providerBaseUrl: process.env.PROVIDER_URL,
|
|
37
|
+
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
|
|
38
|
+
pactBrokerToken: process.env.PACT_BROKER_TOKEN,
|
|
39
|
+
consumerVersionSelectors: [{ mainBranch: true }],
|
|
40
|
+
}).verifyProvider();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Python:**
|
|
44
|
+
```python
|
|
45
|
+
verifier.verify_with_broker(
|
|
46
|
+
broker_url=os.environ['PACT_BROKER_BASE_URL'],
|
|
47
|
+
broker_token=os.environ['PACT_BROKER_TOKEN'],
|
|
48
|
+
consumer_version_selectors=[{'mainBranch': True}],
|
|
49
|
+
)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## CI Integration
|
|
53
|
+
|
|
54
|
+
### Consumer Pipeline
|
|
55
|
+
|
|
56
|
+
1. Run consumer tests → generates pact JSON
|
|
57
|
+
2. Publish pact to broker with version + branch/tag
|
|
58
|
+
3. Trigger provider verification (via webhook or separate job)
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
# GitHub Actions example
|
|
62
|
+
- name: Run consumer tests
|
|
63
|
+
run: npm test -- --grep "Pact"
|
|
64
|
+
|
|
65
|
+
- name: Publish pact
|
|
66
|
+
run: npx pact-broker publish pacts/ --consumer-app-version=${{ github.sha }} --branch=${{ github.ref_name }}
|
|
67
|
+
env:
|
|
68
|
+
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
|
|
69
|
+
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Provider Pipeline
|
|
73
|
+
|
|
74
|
+
1. Fetch pacts from broker (or receive webhook)
|
|
75
|
+
2. Start provider (or use running instance)
|
|
76
|
+
3. Run verification against provider
|
|
77
|
+
4. Publish verification results to broker
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
- name: Verify pacts
|
|
81
|
+
run: npm run pact:verify
|
|
82
|
+
env:
|
|
83
|
+
PROVIDER_URL: http://localhost:3000
|
|
84
|
+
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
|
|
85
|
+
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## can-i-deploy
|
|
89
|
+
|
|
90
|
+
Check if a consumer or provider version is safe to deploy based on verification status.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Can consumer v1.2.3 be deployed?
|
|
94
|
+
pact-broker can-i-deploy --pacticipant=OrderService --version=1.2.3 --to-environment=production
|
|
95
|
+
|
|
96
|
+
# Can provider v2.0.0 be deployed?
|
|
97
|
+
pact-broker can-i-deploy --pacticipant=UserService --version=2.0.0 --to-environment=production
|
|
98
|
+
|
|
99
|
+
# Can both be deployed together?
|
|
100
|
+
pact-broker can-i-deploy --pacticipant=OrderService --version=1.2.3 --pacticipant=UserService --version=2.0.0
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### In CI (pre-deploy gate)
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
- name: Can I deploy?
|
|
107
|
+
run: |
|
|
108
|
+
pact-broker can-i-deploy \
|
|
109
|
+
--pacticipant=OrderService \
|
|
110
|
+
--version=${{ github.sha }} \
|
|
111
|
+
--to-environment=staging
|
|
112
|
+
env:
|
|
113
|
+
PACT_BROKER_BASE_URL: ${{ secrets.PACT_BROKER_BASE_URL }}
|
|
114
|
+
PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Local Development
|
|
118
|
+
|
|
119
|
+
### Without Broker
|
|
120
|
+
|
|
121
|
+
- Consumer: write pact to `pacts/` directory
|
|
122
|
+
- Provider: verify from local `pacts/` path
|
|
123
|
+
- Share pact files via git or file copy
|
|
124
|
+
|
|
125
|
+
### With Broker (Pactflow / self-hosted)
|
|
126
|
+
|
|
127
|
+
- Use broker for all publish/verify
|
|
128
|
+
- Tag versions with branch names for branch-based verification
|
|
129
|
+
- Use `consumerVersionSelectors` to choose which pacts to verify
|
|
130
|
+
|
|
131
|
+
## Versioning
|
|
132
|
+
|
|
133
|
+
- **Consumer version**: Use git SHA, semver, or build number
|
|
134
|
+
- **Provider version**: Same as consumer
|
|
135
|
+
- **Tagging**: Tag with branch (`main`, `develop`) or environment (`production`, `staging`) for can-i-deploy
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Pact Patterns
|
|
2
|
+
|
|
3
|
+
## Consumer Tests
|
|
4
|
+
|
|
5
|
+
### JavaScript/TypeScript (PactV4)
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { PactV4 } from '@pact-foundation/pact';
|
|
9
|
+
|
|
10
|
+
const pact = new PactV4({
|
|
11
|
+
consumer: 'OrderService',
|
|
12
|
+
provider: 'UserService',
|
|
13
|
+
dir: 'pacts',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('User API', () => {
|
|
17
|
+
it('gets user by id', async () => {
|
|
18
|
+
await pact
|
|
19
|
+
.addInteraction()
|
|
20
|
+
.given('user with id 123 exists')
|
|
21
|
+
.uponReceiving('a request for user 123')
|
|
22
|
+
.withRequest('GET', '/users/123')
|
|
23
|
+
.willRespondWith(200, (builder) => {
|
|
24
|
+
builder.jsonBody({
|
|
25
|
+
id: builder.like(123),
|
|
26
|
+
name: builder.like('Alice'),
|
|
27
|
+
email: builder.term({ matcher: '.*@.*', generate: 'alice@example.com' }),
|
|
28
|
+
});
|
|
29
|
+
})
|
|
30
|
+
.executeTest(async (mockServer) => {
|
|
31
|
+
const res = await fetch(`${mockServer.url}/users/123`);
|
|
32
|
+
expect(res.status).toBe(200);
|
|
33
|
+
const body = await res.json();
|
|
34
|
+
expect(body.name).toBe('Alice');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Python (pact-python)
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import pytest
|
|
44
|
+
from pact import Consumer, Provider
|
|
45
|
+
|
|
46
|
+
pact = Consumer('OrderService').has_pact_with(Provider('UserService'))
|
|
47
|
+
pact.start_service()
|
|
48
|
+
pact.given('user with id 123 exists').upon_receiving('a request for user 123').with_request(
|
|
49
|
+
method='GET', path='/users/123'
|
|
50
|
+
).will_respond_with(200, body={'id': Like(123), 'name': Like('Alice'), 'email': Term(r'.*@.*', 'alice@example.com')})
|
|
51
|
+
|
|
52
|
+
@pytest.fixture
|
|
53
|
+
def user_client():
|
|
54
|
+
return UserClient(base_url=pact.uri)
|
|
55
|
+
|
|
56
|
+
def test_get_user(user_client):
|
|
57
|
+
pact.given('user with id 123 exists').upon_receiving('a request for user 123').with_request(
|
|
58
|
+
method='GET', path='/users/123'
|
|
59
|
+
).will_respond_with(200, body={'id': Like(123), 'name': Like('Alice')})
|
|
60
|
+
pact.verify()
|
|
61
|
+
result = user_client.get_user(123)
|
|
62
|
+
assert result['name'] == 'Alice'
|
|
63
|
+
|
|
64
|
+
# Teardown: pact.stop_service()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Provider Verification
|
|
68
|
+
|
|
69
|
+
### JavaScript
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { Verifier } from '@pact-foundation/pact';
|
|
73
|
+
|
|
74
|
+
await new Verifier({
|
|
75
|
+
provider: 'UserService',
|
|
76
|
+
providerBaseUrl: process.env.PROVIDER_URL || 'http://localhost:3000',
|
|
77
|
+
pactUrls: ['pacts/orderservice-userservice.json'],
|
|
78
|
+
stateHandlers: {
|
|
79
|
+
'user with id 123 exists': async () => {
|
|
80
|
+
await seedUser({ id: 123, name: 'Alice', email: 'alice@example.com' });
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
}).verifyProvider();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Python
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from pact import Verifier
|
|
90
|
+
|
|
91
|
+
verifier = Verifier(
|
|
92
|
+
provider='UserService',
|
|
93
|
+
provider_base_url='http://localhost:3000',
|
|
94
|
+
)
|
|
95
|
+
verifier.verify_pacts(
|
|
96
|
+
'pacts/orderservice-userservice.json',
|
|
97
|
+
state_handler={
|
|
98
|
+
'user with id 123 exists': lambda: seed_user(id=123, name='Alice', email='alice@example.com'),
|
|
99
|
+
},
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Functional State Handlers (Python v2.3+)
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
def state_handler(state: str, params: dict | None = None) -> dict | None:
|
|
107
|
+
if state == 'user with id 123 exists':
|
|
108
|
+
seed_user(id=123, name='Alice', email='alice@example.com')
|
|
109
|
+
return None
|
|
110
|
+
if state == 'user has orders':
|
|
111
|
+
user_id = params.get('userId') if params else None
|
|
112
|
+
seed_orders(user_id=user_id)
|
|
113
|
+
return None
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
verifier.verify_pacts('pacts/...', state_handler=state_handler)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Matchers
|
|
120
|
+
|
|
121
|
+
| Matcher | Purpose | JS Example | Python Example |
|
|
122
|
+
| ------- | ------- | ---------- | -------------- |
|
|
123
|
+
| **like** | Any value of same type | `builder.like(123)` | `Like(123)` |
|
|
124
|
+
| **eachLike** | Array of objects matching template | `builder.eachLike({ id: 1 })` | `EachLike({'id': 1})` |
|
|
125
|
+
| **term** | Regex match with example | `builder.term({ matcher: '\\d+', generate: '42' })` | `Term(r'\d+', '42')` |
|
|
126
|
+
| **regex** | Alias for term | Same as term | Same as term |
|
|
127
|
+
| **integer** | Integer type | `builder.integer(1)` | `Integer(1)` |
|
|
128
|
+
| **decimal** | Decimal type | `builder.decimal(1.5)` | `Decimal(1.5)` |
|
|
129
|
+
| **boolean** | Boolean type | `builder.boolean(true)` | `Boolean(True)` |
|
|
130
|
+
| **uuid** | UUID format | `builder.uuid()` | `Uuid()` |
|
|
131
|
+
| **datetime** | ISO datetime | `builder.datetime()` | `Datetime()` |
|
|
132
|
+
|
|
133
|
+
### Matcher Best Practices
|
|
134
|
+
|
|
135
|
+
- Use `like` for IDs, timestamps, and other dynamic values
|
|
136
|
+
- Use `eachLike` for arrays; specify min count if needed: `eachLike(obj, min=1)`
|
|
137
|
+
- Use `term` when format matters (email, phone, slug)
|
|
138
|
+
- Avoid over-specifying; match only what the consumer needs
|
|
139
|
+
|
|
140
|
+
## Provider States
|
|
141
|
+
|
|
142
|
+
### Naming Convention
|
|
143
|
+
|
|
144
|
+
- Use descriptive, scenario-based names: `user with id X exists`, `order is pending`
|
|
145
|
+
- Match exactly between consumer `given()` and provider state handler key
|
|
146
|
+
- Prefer parameterized states when possible: `user with id {userId} exists`
|
|
147
|
+
|
|
148
|
+
### State Handler Responsibilities
|
|
149
|
+
|
|
150
|
+
1. **Setup** — Create data, set DB state, mock external services
|
|
151
|
+
2. **Isolation** — Each interaction runs in isolation; no shared state between interactions
|
|
152
|
+
3. **Teardown** — Clean up after verification (optional; provider may reset per interaction)
|
|
153
|
+
|
|
154
|
+
### Common Patterns
|
|
155
|
+
|
|
156
|
+
| State | Setup |
|
|
157
|
+
| ----- | ----- |
|
|
158
|
+
| `user exists` | Insert user into test DB |
|
|
159
|
+
| `user has no orders` | Ensure orders table empty for user |
|
|
160
|
+
| `order is pending` | Insert order with status PENDING |
|
|
161
|
+
| `auth token valid` | Seed valid token or mock auth service |
|