59 / 65 · 14 API Testing Fundamentals · API Versioning← prev⊞ allnext →☰ Read as one page
8.2Versioning Strategies
| Strategy | Example | Pros | Cons |
|---|---|---|---|
| URL path | /v1/users, /v2/users |
Clear, easy to route | URL pollution, hard to remove old versions |
| Header | Accept: application/vnd.api+json; version=2 |
Clean URLs | Harder to test manually, easy to miss |
| Query param | /users?version=2 |
Simple | URL pollution, caching complications |
| Content negotiation | Accept: application/vnd.company.v2+json |
RESTful | Complex to implement and test |
URL Path Versioning (Most Common)
def test_v1_users_endpoint(api):
r = api.get("/v1/users")
assert r.status_code == 200
user = r.json()["items"][0]
assert "name" in user # v1 returns "name"
def test_v2_users_endpoint(api):
r = api.get("/v2/users")
assert r.status_code == 200
user = r.json()["items"][0]
assert "first_name" in user # v2 splits into first/last
assert "last_name" in user
Header-Based Versioning
def test_header_versioning(api, base_url):
# Default version (no header)
r = api.get("/users")
assert r.status_code == 200
default_fields = set(r.json()["items"][0].keys())
# Explicit v2
r = api.get("/users", headers={"API-Version": "2"})
assert r.status_code == 200
v2_fields = set(r.json()["items"][0].keys())
# v2 should have new fields
assert "first_name" in v2_fields
assert "last_name" in v2_fields
def test_missing_version_header_uses_default(api):
"""When no version header is sent, the API should use the default version."""
r = api.get("/users")
assert r.status_code == 200
# Verify it returns the default version's response format