Skip to main content
Back to API Types
📜

Contract Testing Lab

Practice detecting breaking changes between API v1 and v2

API v2 introduces several breaking changes. Use these to practice contract testing, schema validation, and migration scripts.

Users(4 changes)

Renamedname → fullName

Field renamed from "name" to "fullName"

v1
name: string
v2
fullName: string
Addedphone

New required field added

v2
phone: string (required)
Addedmetadata

New metadata object with version tracking

v2
metadata: { version, createdAt, updatedAt }
Structureresponse wrapper

Response structure changed

v1
{ data: [...], total }
v2
{ users: [...], meta: {...} }

Products(5 changes)

Structureprice → pricing

Simple number replaced with object

v1
price: 99.99
v2
pricing: { amount: 99.99, currency: "USD", formatted: "$99.99" }
StructureinStock → availability

Boolean replaced with object

v1
inStock: true
v2
availability: { status: "in_stock", quantity: 50 }
Addedtags

New array field for product tags

v2
tags: string[]
Renamedquery params

Filter parameter names changed

v1
minPrice, maxPrice, inStock
v2
minAmount, maxAmount, availability
Structureresponse wrapper

Response structure changed

v1
{ data: [...], pagination }
v2
{ products: [...], meta: {...} }

Contract Testing Practice

What to Test

  • Field renames (name → fullName)
  • New required fields (phone)
  • Type changes (price: number → pricing: object)
  • Response structure changes (data → users/products)
  • Query parameter renames

Tools to Use

  • Pact for consumer-driven contracts
  • OpenAPI diff tools (oasdiff, optic)
  • JSON Schema validators
  • Postman contract tests
  • RestAssured schema validation

Example Test Cases

// Test: Detect breaking change in user response
test('v2 users response has fullName instead of name', async () => {
  const v1 = await fetch('/api/v1/users').then(r => r.json());
  const v2 = await fetch('/api/v2/users').then(r => r.json());

  // v1 uses "data" wrapper, v2 uses "users"
  expect(v1).toHaveProperty('data');
  expect(v2).toHaveProperty('users');

  // v1 has "name", v2 has "fullName"
  expect(v1.data[0]).toHaveProperty('name');
  expect(v2.users[0]).toHaveProperty('fullName');
  expect(v2.users[0]).not.toHaveProperty('name');
});
Contract Testing Lab by World of QA