Removed field
GET /api/v1/users/:id- before:
- { id, name, email, username }
- after:
- { id, name, email }
Consumers reading user.username break silently until runtime.
Contract testing prevents "works on my service, breaks in yours." Compare OpenAPI v1 vs v2 of the Practice API, then see how Pact, Schemathesis, and openapi-diff surface breaking changes before they ship.
GET /api/openapi?version=v1 โ original spec (stable contract)GET /api/openapi?version=v2 โ evolved spec with breaking changesGET /api/openapi?version=full โ current full spec (all endpoints)GET /api/v1/users/:idConsumers reading user.username break silently until runtime.
GET /api/v1/posts/:idRename-only refactors can be detected via OpenAPI diff before deploy.
POST /api/v1/usersProvider relaxation. Usually safe, but consumer validators may now accept invalid data.
GET /api/v1/products/:idHard break. Consumer math on price silently fails at runtime.
The consumer defines expectations. The provider later verifies those expectations hold. Best for tightly-coupled teams.
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
const provider = new PactV3({
consumer: 'WebApp',
provider: 'PracticeAPI',
});
describe('GET /api/v1/users/:id', () => {
it('returns a user with id, name, email', async () => {
provider
.given('user 1 exists')
.uponReceiving('a request for user 1')
.withRequest({ method: 'GET', path: '/api/v1/users/1' })
.willRespondWith({
status: 200,
headers: { 'Content-Type': 'application/json' },
body: {
id: MatchersV3.like('1'),
name: MatchersV3.string('Alice'),
email: MatchersV3.email('alice@example.com'),
},
});
await provider.executeTest(async (mock) => {
const res = await fetch(`${mock.url}/api/v1/users/1`);
expect(res.status).toBe(200);
});
});
});Reads your OpenAPI spec, generates thousands of requests, finds edge cases the spec allows but your server rejects.
# Install: pip install schemathesis
# Property-based tests against the live API using the OpenAPI spec.
schemathesis run \
--url https://api.qa-practice.dev \
https://api.qa-practice.dev/api/openapi?version=v2 \
--checks all \
--hypothesis-max-examples=100CI-friendly diff between two OpenAPI specs. Zero runtime cost, catches most structural breaks before deploy.
# Detect breaking changes between v1 and v2 from CI:
npx openapi-diff \
https://api.qa-practice.dev/api/openapi?version=v1 \
https://api.qa-practice.dev/api/openapi?version=v2
# Non-zero exit = breaking changes detected. Fail the PR.