/configure:api-tests Check and configure API contract testing infrastructure for validating API contracts, schemas, and consumer-provider agreements. When to Use This Skill | Use this skill when... | Use another approach when... | |------------------------|------------------------------| | Setting up Pact consumer/provider contract tests | Writing individual unit tests ( ) | | Configuring OpenAPI request/response validation | Validating a single API endpoint manually | | Adding JSON Schema or Zod schema testing | Checking general test coverage ( ) | | Detecting breaking API changes in CI | Re…

, '[email protected]'),\n }\n\n (pact_setup\n .given('a user with ID 1 exists')\n .upon_receiving('a request to get user 1')\n .with_request('GET', '/api/users/1')\n .will_respond_with(200, body=expected))\n\n with pact_setup:\n result = requests.get(f'{pact_setup.uri}/api/users/1')\n\n assert result.status_code == 200\n assert 'id' in result.json()\n assert 'name' in result.json()\n\ndef test_get_nonexistent_user(pact_setup):\n \"\"\"Test 404 response for non-existent user.\"\"\"\n (pact_setup\n .given('no user with ID 999 exists')\n .upon_receiving('a request to get non-existent user')\n .with_request('GET', '/api/users/999')\n .will_respond_with(404, body={\n 'error': Like('User not found'),\n 'code': Like('USER_NOT_FOUND'),\n }))\n\n with pact_setup:\n result = requests.get(f'{pact_setup.uri}/api/users/999')\n\n assert result.status_code == 404\n```\n\n## OpenAPI Validation (JavaScript/TypeScript)\n\n### Install Dependencies\n\n```bash\nbun add --dev @apidevtools/swagger-parser ajv ajv-formats\nbun add --dev openapi-typescript # For TypeScript types from OpenAPI\n```\n\n### OpenAPI Validator (`tests/api/openapi-validator.ts`)\n\n```typescript\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport SwaggerParser from '@apidevtools/swagger-parser';\nimport { OpenAPIV3 } from 'openapi-types';\n\nexport class OpenAPIValidator {\n private ajv: Ajv;\n private spec: OpenAPIV3.Document | null = null;\n private schemas: Map\u003cstring, object> = new Map();\n\n constructor() {\n this.ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(this.ajv);\n }\n\n async loadSpec(specPath: string): Promise\u003cvoid> {\n this.spec = await SwaggerParser.validate(specPath) as OpenAPIV3.Document;\n\n if (this.spec.components?.schemas) {\n for (const [name, schema] of Object.entries(this.spec.components.schemas)) {\n this.schemas.set(name, schema);\n this.ajv.addSchema(schema, `#/components/schemas/${name}`);\n }\n }\n }\n\n validateResponse(\n path: string,\n method: string,\n statusCode: number,\n body: unknown\n ): { valid: boolean; errors: string[] } {\n if (!this.spec) {\n throw new Error('OpenAPI spec not loaded. Call loadSpec() first.');\n }\n\n const pathItem = this.spec.paths?.[path];\n if (!pathItem) {\n return { valid: false, errors: [`Path ${path} not found in spec`] };\n }\n\n const operation = pathItem[method.toLowerCase() as keyof OpenAPIV3.PathItemObject] as OpenAPIV3.OperationObject;\n if (!operation) {\n return { valid: false, errors: [`Method ${method} not found for path ${path}`] };\n }\n\n const response = operation.responses?.[statusCode] || operation.responses?.['default'];\n if (!response) {\n return { valid: false, errors: [`Status ${statusCode} not defined for ${method} ${path}`] };\n }\n\n const responseObj = response as OpenAPIV3.ResponseObject;\n const content = responseObj.content?.['application/json'];\n if (!content?.schema) {\n return { valid: true, errors: [] };\n }\n\n const validate = this.ajv.compile(content.schema);\n const valid = validate(body);\n\n return {\n valid: !!valid,\n errors: validate.errors?.map(e => `${e.instancePath} ${e.message}`) || [],\n };\n }\n\n validateRequest(\n path: string,\n method: string,\n body: unknown\n ): { valid: boolean; errors: string[] } {\n if (!this.spec) {\n throw new Error('OpenAPI spec not loaded. Call loadSpec() first.');\n }\n\n const pathItem = this.spec.paths?.[path];\n if (!pathItem) {\n return { valid: false, errors: [`Path ${path} not found in spec`] };\n }\n\n const operation = pathItem[method.toLowerCase() as keyof OpenAPIV3.PathItemObject] as OpenAPIV3.OperationObject;\n if (!operation?.requestBody) {\n return { valid: true, errors: [] };\n }\n\n const requestBody = operation.requestBody as OpenAPIV3.RequestBodyObject;\n const content = requestBody.content?.['application/json'];\n if (!content?.schema) {\n return { valid: true, errors: [] };\n }\n\n const validate = this.ajv.compile(content.schema);\n const valid = validate(body);\n\n return {\n valid: !!valid,\n errors: validate.errors?.map(e => `${e.instancePath} ${e.message}`) || [],\n };\n }\n}\n\nexport async function createValidator(specPath: string = './openapi.yaml'): Promise\u003cOpenAPIValidator> {\n const validator = new OpenAPIValidator();\n await validator.loadSpec(specPath);\n return validator;\n}\n```\n\n### OpenAPI Test Template (`tests/api/users.openapi.test.ts`)\n\n```typescript\nimport { describe, it, expect, beforeAll } from 'vitest';\nimport request from 'supertest';\nimport { app } from '../../src/app';\nimport { createValidator, OpenAPIValidator } from './openapi-validator';\n\ndescribe('Users API - OpenAPI Compliance', () => {\n let validator: OpenAPIValidator;\n\n beforeAll(async () => {\n validator = await createValidator('./openapi.yaml');\n });\n\n describe('GET /api/users', () => {\n it('response matches OpenAPI schema', async () => {\n const response = await request(app)\n .get('/api/users')\n .expect(200);\n\n const result = validator.validateResponse('/api/users', 'GET', 200, response.body);\n\n expect(result.valid).toBe(true);\n if (!result.valid) {\n console.error('Validation errors:', result.errors);\n }\n });\n });\n\n describe('POST /api/users', () => {\n it('request matches OpenAPI schema', async () => {\n const requestBody = {\n name: 'Test User',\n email: '[email protected]',\n };\n\n const requestValidation = validator.validateRequest('/api/users', 'POST', requestBody);\n expect(requestValidation.valid).toBe(true);\n\n const response = await request(app)\n .post('/api/users')\n .send(requestBody)\n .expect(201);\n\n const responseValidation = validator.validateResponse('/api/users', 'POST', 201, response.body);\n expect(responseValidation.valid).toBe(true);\n });\n\n it('rejects invalid request body', async () => {\n const invalidBody = {\n name: 123, // Should be string\n // Missing required email\n };\n\n const validation = validator.validateRequest('/api/users', 'POST', invalidBody);\n expect(validation.valid).toBe(false);\n expect(validation.errors.length).toBeGreaterThan(0);\n });\n });\n\n describe('GET /api/users/:id', () => {\n it('404 response matches OpenAPI schema', async () => {\n const response = await request(app)\n .get('/api/users/99999')\n .expect(404);\n\n const result = validator.validateResponse('/api/users/{id}', 'GET', 404, response.body);\n expect(result.valid).toBe(true);\n });\n });\n});\n```\n\n## OpenAPI Breaking Change Detection\n\n### Install oasdiff\n\n```bash\nbun add --dev @oasdiff/oasdiff\n# Or via homebrew\nbrew install oasdiff\n```\n\n### CI Workflow Step\n\n```yaml\n- name: Check for breaking API changes\n run: |\n git fetch origin main\n git show origin/main:openapi.yaml > openapi-main.yaml\n\n oasdiff breaking openapi-main.yaml openapi.yaml --fail-on ERR\n oasdiff changelog openapi-main.yaml openapi.yaml\n```\n\n## Schema Testing with Zod\n\n### Install Dependencies\n\n```bash\nbun add zod\nbun add --dev @anatine/zod-openapi # Optional: generate OpenAPI from Zod\n```\n\n### Schema Definitions (`src/schemas/user.ts`)\n\n```typescript\nimport { z } from 'zod';\n\nexport const UserSchema = z.object({\n id: z.number().int().positive(),\n name: z.string().min(1).max(100),\n email: z.string().email(),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime().optional(),\n});\n\nexport const CreateUserSchema = UserSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n});\n\nexport const UpdateUserSchema = CreateUserSchema.partial();\n\nexport const UserListSchema = z.array(UserSchema);\n\nexport type User = z.infer\u003ctypeof UserSchema>;\nexport type CreateUser = z.infer\u003ctypeof CreateUserSchema>;\nexport type UpdateUser = z.infer\u003ctypeof UpdateUserSchema>;\n```\n\n### Schema Test Template (`tests/api/schema.test.ts`)\n\n```typescript\nimport { describe, it, expect } from 'vitest';\nimport request from 'supertest';\nimport { app } from '../../src/app';\nimport { UserSchema, UserListSchema } from '../../src/schemas/user';\n\ndescribe('API Schema Validation', () => {\n describe('GET /api/users', () => {\n it('response matches User list schema', async () => {\n const response = await request(app)\n .get('/api/users')\n .expect(200);\n\n const result = UserListSchema.safeParse(response.body);\n\n expect(result.success).toBe(true);\n if (!result.success) {\n console.error('Schema errors:', result.error.format());\n }\n });\n });\n\n describe('GET /api/users/:id', () => {\n it('response matches User schema', async () => {\n const response = await request(app)\n .get('/api/users/1')\n .expect(200);\n\n const result = UserSchema.safeParse(response.body);\n\n expect(result.success).toBe(true);\n });\n });\n});\n```\n\n## CI/CD Workflow Template\n\n### `.github/workflows/api-tests.yml`\n\n```yaml\nname: API Contract Tests\n\non:\n push:\n branches: [main]\n pull_request:\n paths:\n - 'openapi.yaml'\n - 'src/api/**'\n - 'tests/contract/**'\n\njobs:\n consumer-tests:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - uses: oven-sh/setup-bun@v2\n\n - name: Install dependencies\n run: bun install --frozen-lockfile\n\n - name: Run consumer contract tests\n run: bun run test:contract:consumer\n\n - name: Upload pacts\n uses: actions/upload-artifact@v4\n with:\n name: pacts\n path: pacts/\n\n provider-tests:\n runs-on: ubuntu-latest\n needs: consumer-tests\n services:\n postgres:\n image: postgres:16-alpine\n env:\n POSTGRES_USER: test\n POSTGRES_PASSWORD: test\n POSTGRES_DB: test_db\n ports:\n - 5432:5432\n\n steps:\n - uses: actions/checkout@v4\n\n - uses: oven-sh/setup-bun@v2\n\n - name: Install dependencies\n run: bun install --frozen-lockfile\n\n - name: Download pacts\n uses: actions/download-artifact@v4\n with:\n name: pacts\n path: pacts/\n\n - name: Run provider verification\n run: bun run test:contract:provider\n env:\n DATABASE_URL: postgresql://test:test@localhost:5432/test_db\n\n openapi-validation:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n with:\n fetch-depth: 0\n\n - name: Validate OpenAPI spec\n run: |\n bunx @apidevtools/swagger-cli validate openapi.yaml\n\n - name: Check for breaking changes\n if: github.event_name == 'pull_request'\n run: |\n git fetch origin main\n git show origin/main:openapi.yaml > openapi-main.yaml || echo \"No existing spec\"\n\n if [ -f openapi-main.yaml ]; then\n bunx oasdiff breaking openapi-main.yaml openapi.yaml --fail-on ERR\n fi\n\n # Optional: Publish to Pact Broker\n publish-pacts:\n runs-on: ubuntu-latest\n needs: [consumer-tests, provider-tests]\n if: github.ref == 'refs/heads/main'\n steps:\n - uses: actions/checkout@v4\n\n - name: Download pacts\n uses: actions/download-artifact@v4\n with:\n name: pacts\n path: pacts/\n\n - name: Publish to Pact Broker\n run: |\n curl -X PUT \\\n -H \"Content-Type: application/json\" \\\n -d @pacts/frontend-app-user-service.json \\\n \"${{ secrets.PACT_BROKER_URL }}/pacts/provider/user-service/consumer/frontend-app/version/${{ github.sha }}\"\n env:\n PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN }}\n```\n\n## Package.json Scripts\n\n```json\n{\n \"scripts\": {\n \"test:contract\": \"bun run test:contract:consumer && bun run test:contract:provider\",\n \"test:contract:consumer\": \"vitest run tests/contract/consumer/\",\n \"test:contract:provider\": \"vitest run tests/contract/provider/\",\n \"test:openapi\": \"vitest run tests/api/*.openapi.test.ts\",\n \"test:schema\": \"vitest run tests/api/schema.test.ts\",\n \"openapi:validate\": \"bunx @apidevtools/swagger-cli validate openapi.yaml\",\n \"openapi:bundle\": \"bunx @apidevtools/swagger-cli bundle openapi.yaml -o dist/openapi.json\",\n \"openapi:types\": \"bunx openapi-typescript openapi.yaml -o src/types/api.d.ts\"\n }\n}\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":18724,"content_sha256":"7b16b0abcfb25b0311715c525615aa757f5a9e2ba7bb91c890d6180aa7531f6d"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"/configure:api-tests","type":"text"}]},{"type":"paragraph","content":[{"text":"Check and configure API contract testing infrastructure for validating API contracts, schemas, and consumer-provider agreements.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use this skill when...","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use another approach when...","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Setting up Pact consumer/provider contract tests","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Writing individual unit tests (","type":"text"},{"text":"/configure:tests","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Configuring OpenAPI request/response validation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Validating a single API endpoint manually","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Adding JSON Schema or Zod schema testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Checking general test coverage (","type":"text"},{"text":"/configure:coverage","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Detecting breaking API changes in CI","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reviewing API design decisions (code-review agent)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Auditing API testing compliance across a project","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Configuring general CI/CD workflows (","type":"text"},{"text":"/configure:workflows","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Context","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Project root: !","type":"text"},{"text":"pwd","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Package files: !","type":"text"},{"text":"find . -maxdepth 1 \\( -name 'package.json' -o -name 'pyproject.toml' \\)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact deps: !","type":"text"},{"text":"find . -maxdepth 1 \\( -name package.json -o -name pyproject.toml \\) -exec grep -l 'pact' {} +","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenAPI spec: !","type":"text"},{"text":"find . -maxdepth 1 \\( -name 'openapi.yaml' -o -name 'openapi.json' -o -name 'swagger.json' \\)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact dir: !","type":"text"},{"text":"find . -maxdepth 1 -type d -name 'pacts'","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Contract tests: !","type":"text"},{"text":"find tests -maxdepth 2 -type d -name 'contract'","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Project standards: !","type":"text"},{"text":"find . -maxdepth 1 -name '.project-standards.yaml'","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Parameters","type":"text"}]},{"type":"paragraph","content":[{"text":"Parse from command arguments:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--check-only","type":"text","marks":[{"type":"code_inline"}]},{"text":": Report compliance status without modifications (CI/CD mode)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--fix","type":"text","marks":[{"type":"code_inline"}]},{"text":": Apply fixes automatically without prompting","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--type \u003cpact|openapi|schema>","type":"text","marks":[{"type":"code_inline"}]},{"text":": Focus on specific type","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"API Testing Types:","type":"text","marks":[{"type":"strong"}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Case","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pact","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microservices, multiple consumers, breaking change detection","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OpenAPI","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API-first development, documentation-driven testing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Schema","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Simple validation, GraphQL APIs, single service","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Execution","type":"text"}]},{"type":"paragraph","content":[{"text":"Execute this API testing compliance check:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Detect existing API testing infrastructure","type":"text"}]},{"type":"paragraph","content":[{"text":"Check for these indicators:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Indicator","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Component","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pact","type":"text","marks":[{"type":"code_inline"}]},{"text":" in dependencies","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pact contract testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Installed","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"openapi.yaml","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"swagger.json","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OpenAPI specification","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Present","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"@apidevtools/swagger-parser","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OpenAPI validation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Configured","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ajv","type":"text","marks":[{"type":"code_inline"}]},{"text":" in dependencies","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"JSON Schema validation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Configured","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pacts/","type":"text","marks":[{"type":"code_inline"}]},{"text":" directory","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pact contracts","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Present","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Analyze current state","type":"text"}]},{"type":"paragraph","content":[{"text":"For each detected component, check completeness:","type":"text"}]},{"type":"paragraph","content":[{"text":"Contract Testing (Pact):","type":"text","marks":[{"type":"strong"}]}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"@pact-foundation/pact","type":"text","marks":[{"type":"code_inline"}]},{"text":" installed (JS) or ","type":"text"},{"text":"pact-python","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Python)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Consumer tests defined","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Provider verification configured","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Pact Broker or PactFlow configured (optional)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"CI/CD pipeline integration","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"OpenAPI Validation:","type":"text","marks":[{"type":"strong"}]}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"OpenAPI specification file exists","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Request validation middleware configured","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Response validation in tests","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Schema auto-generation configured","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Breaking change detection","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Schema Testing:","type":"text","marks":[{"type":"strong"}]}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"JSON Schema definitions exist","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"ajv","type":"text","marks":[{"type":"code_inline"}]},{"text":" or similar validator installed","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Response validation helpers","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Schema versioning strategy","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Generate compliance report","type":"text"}]},{"type":"paragraph","content":[{"text":"Print a formatted compliance report:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"API Testing Compliance Report\n==============================\nProject: [name]\nAPI Type: [REST | GraphQL | gRPC]\n\nContract Testing (Pact):\n @pact-foundation/pact package.json [INSTALLED | MISSING]\n Consumer tests tests/contract/consumer/ [FOUND | NONE]\n Provider tests tests/contract/provider/ [FOUND | NONE]\n Pact Broker CI configuration [CONFIGURED | OPTIONAL]\n can-i-deploy CI gate [CONFIGURED | OPTIONAL]\n\nOpenAPI Validation:\n OpenAPI spec openapi.yaml [EXISTS | MISSING]\n Spec version OpenAPI 3.1 [CURRENT | OUTDATED]\n Request validation middleware [CONFIGURED | MISSING]\n Response validation test helpers [CONFIGURED | MISSING]\n Breaking change CI oasdiff [CONFIGURED | OPTIONAL]\n\nSchema Testing:\n JSON Schemas schemas/ [EXISTS | N/A]\n Schema validator ajv/zod [INSTALLED | MISSING]\n Response validation test helpers [CONFIGURED | MISSING]\n\nOverall: [X issues found]\n\nRecommendations:\n - Add Pact consumer tests for service dependencies\n - Configure OpenAPI response validation in tests\n - Add breaking change detection to CI","type":"text"}]},{"type":"paragraph","content":[{"text":"If ","type":"text"},{"text":"--check-only","type":"text","marks":[{"type":"code_inline"}]},{"text":", stop here.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Configure API testing (if --fix or user confirms)","type":"text"}]},{"type":"paragraph","content":[{"text":"Apply fixes based on detected project type. Use templates from ","type":"text"},{"text":"REFERENCE.md","type":"text","marks":[{"type":"link","attrs":{"href":"REFERENCE.md","title":null}}]},{"text":" for:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact Contract Testing","type":"text","marks":[{"type":"strong"}]},{"text":" - Install dependencies and create consumer/provider test files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenAPI Validation","type":"text","marks":[{"type":"strong"}]},{"text":" - Install validator and create test helpers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Schema Testing with Zod","type":"text","marks":[{"type":"strong"}]},{"text":" - Install Zod and create schema definitions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Breaking Change Detection","type":"text","marks":[{"type":"strong"}]},{"text":" - Install oasdiff and add CI check","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"For JavaScript/TypeScript projects, install with ","type":"text"},{"text":"bun add --dev","type":"text","marks":[{"type":"code_inline"}]},{"text":". For Python, install with ","type":"text"},{"text":"uv add --group dev","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Configure CI/CD integration","type":"text"}]},{"type":"paragraph","content":[{"text":"Create ","type":"text"},{"text":".github/workflows/api-tests.yml","type":"text","marks":[{"type":"code_inline"}]},{"text":" with jobs for:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Consumer contract tests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provider verification (with service containers if needed)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenAPI spec validation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Breaking change detection on PRs","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Add npm/bun scripts to ","type":"text"},{"text":"package.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" for local testing. Use workflow templates from ","type":"text"},{"text":"REFERENCE.md","type":"text","marks":[{"type":"link","attrs":{"href":"REFERENCE.md","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Update standards tracking","type":"text"}]},{"type":"paragraph","content":[{"text":"Update ","type":"text"},{"text":".project-standards.yaml","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"standards_version: \"2025.1\"\nlast_configured: \"[timestamp]\"\ncomponents:\n api_tests: \"2025.1\"\n api_tests_contract: \"[pact|none]\"\n api_tests_openapi: true\n api_tests_schema: \"[zod|ajv|none]\"\n api_tests_breaking_change_ci: true","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: Print final report","type":"text"}]},{"type":"paragraph","content":[{"text":"Print a summary of all changes applied, scripts added, and next steps for the user to verify the configuration.","type":"text"}]},{"type":"paragraph","content":[{"text":"For detailed templates and code examples, see ","type":"text"},{"text":"REFERENCE.md","type":"text","marks":[{"type":"link","attrs":{"href":"REFERENCE.md","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Agentic Optimizations","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Context","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Command","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quick compliance check","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"/configure:api-tests --check-only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Auto-fix all issues","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"/configure:api-tests --fix","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pact contracts only","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"/configure:api-tests --fix --type pact","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OpenAPI validation only","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"/configure:api-tests --fix --type openapi","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Schema testing only","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"/configure:api-tests --fix --type schema","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Flags","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flag","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--check-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Report status without offering fixes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--fix","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Apply all fixes automatically without prompting","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--type \u003ctype>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Focus on specific type (pact, openapi, schema)","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Examples","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check compliance and offer fixes\n/configure:api-tests\n\n# Check only, no modifications\n/configure:api-tests --check-only\n\n# Auto-fix all issues\n/configure:api-tests --fix\n\n# Configure Pact only\n/configure:api-tests --fix --type pact\n\n# Configure OpenAPI validation only\n/configure:api-tests --fix --type openapi","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Error Handling","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No OpenAPI spec found","type":"text","marks":[{"type":"strong"}]},{"text":": Offer to create template","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact version mismatch","type":"text","marks":[{"type":"strong"}]},{"text":": Suggest upgrade path","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Schema validation fails","type":"text","marks":[{"type":"strong"}]},{"text":": Report specific errors","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact Broker not configured","type":"text","marks":[{"type":"strong"}]},{"text":": Provide setup instructions","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"See Also","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/configure:tests","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Unit testing configuration","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/configure:integration-tests","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Integration testing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/configure:all","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Run all compliance checks","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pact documentation","type":"text","marks":[{"type":"strong"}]},{"text":": https://docs.pact.io","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OpenAPI specification","type":"text","marks":[{"type":"strong"}]},{"text":": https://swagger.io/specification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Zod documentation","type":"text","marks":[{"type":"strong"}]},{"text":": https://zod.dev","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"args":"[--check-only] [--fix] [--type \u003cpact|openapi|schema>]","date":"2026-06-05","name":"configure-api-tests","author":"@skillopedia","source":{"stars":35,"repo_name":"claude-plugins","origin_url":"https://github.com/laurigates/claude-plugins/blob/HEAD/configure-plugin/skills/configure-api-tests/SKILL.md","repo_owner":"laurigates","body_sha256":"32a185d0da38c527d0acb4d11d6d939909b9288189b3f8e0331458f8f5e7a44d","cluster_key":"4dd86f04ed7c32fa76b3fa58b132c3713bfb6891b79d201da55baf0dc8fbd427","clean_bundle":{"format":"clean-skill-bundle-v1","source":"laurigates/claude-plugins/configure-plugin/skills/configure-api-tests/SKILL.md","attachments":[{"id":"dc82d5a4-39de-5e86-9c99-6443743d9ef3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/dc82d5a4-39de-5e86-9c99-6443743d9ef3/attachment.md","path":"REFERENCE.md","size":18724,"sha256":"7b16b0abcfb25b0311715c525615aa757f5a9e2ba7bb91c890d6180aa7531f6d","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"6f14220a19002ed5d317d8365279e61be3e1e80307cefd4e08a2ba595c1a4d09","attachment_count":1,"text_attachments":1,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"configure-plugin/skills/configure-api-tests/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"testing-qa","category_label":"Testing"},"exact_dupes_collapsed_into_this":0},"created":"2025-12-16T00:00:00.000Z","version":"v1","category":"testing-qa","modified":"2026-04-19T00:00:00.000Z","reviewed":"2025-12-16T00:00:00.000Z","import_tag":"clean-skills-v1","description":"API contract testing: Pact, OpenAPI validation, JSON Schema/Zod. Use when adding consumer/provider contract tests or detecting breaking API changes in CI.","allowed-tools":"Glob, Grep, Read, Write, Edit, Bash, AskUserQuestion, TodoWrite","argument-hint":"[--check-only] [--fix] [--type \u003cpact|openapi|schema>]"}},"renderedAt":1782979962838}

/configure:api-tests Check and configure API contract testing infrastructure for validating API contracts, schemas, and consumer-provider agreements. When to Use This Skill | Use this skill when... | Use another approach when... | |------------------------|------------------------------| | Setting up Pact consumer/provider contract tests | Writing individual unit tests ( ) | | Configuring OpenAPI request/response validation | Validating a single API endpoint manually | | Adding JSON Schema or Zod schema testing | Checking general test coverage ( ) | | Detecting breaking API changes in CI | Re…