61 pytest tests generated from Swagger Petstore
Generated from your public OpenAPI spec. They cover the happy path, missing auth, missing required params, wrong types and response-schema checks for each endpoint. Plus 3 multi-step flows that create a resource and pass its id through read, update and delete. Generated, not run against your API — point API_BASE_URL at a test environment and run pytest.
import os
import pytest
import requests
from jsonschema import validate # pip install jsonschema
BASE_URL = os.environ.get("API_BASE_URL", "http://localhost:8000")
class TestUpdatePet:
"""Tests for PUT /pet"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.put(url=BASE_URL + "/pet", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.put(url=BASE_URL + "/pet")
assert response.status_code == 401
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.put(url=BASE_URL + "/pet", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}
validate(instance=response.json(), schema=schema)
class TestAddPet:
"""Tests for POST /pet"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/pet", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.post(url=BASE_URL + "/pet")
assert response.status_code == 401
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/pet", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}
validate(instance=response.json(), schema=schema)
class TestFindPetsByStatus:
"""Tests for GET /pet/findByStatus"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/pet/findByStatus", params={'status': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.get(url=BASE_URL + "/pet/findByStatus", params={'status': 'example'})
assert response.status_code == 401
def test_missing_status(self):
"""Missing required param 'status' — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/pet/findByStatus", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_invalid_types(self):
"""Invalid field types — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/pet/findByStatus", params={'status': 'INVALID_TYPE_$$'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/pet/findByStatus", params={'status': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'array', 'items': {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}}
validate(instance=response.json(), schema=schema)
class TestFindPetsByTags:
"""Tests for GET /pet/findByTags"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/pet/findByTags", params={'tags': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.get(url=BASE_URL + "/pet/findByTags", params={'tags': 'example'})
assert response.status_code == 401
def test_missing_tags(self):
"""Missing required param 'tags' — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/pet/findByTags", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_invalid_types(self):
"""Invalid field types — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/pet/findByTags", params={'tags': 'INVALID_TYPE_$$'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/pet/findByTags", params={'tags': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'array', 'items': {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}}
validate(instance=response.json(), schema=schema)
class TestGetPetById:
"""Tests for GET /pet/{petId}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/pet/1", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.get(url=BASE_URL + "/pet/1")
assert response.status_code == 401
def test_missing_petId(self):
"""Missing required param 'petId' — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/pet/1", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/pet/1", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}
validate(instance=response.json(), schema=schema)
class TestUpdatePetWithForm:
"""Tests for POST /pet/{petId}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/pet/1", params={'name': 'example', 'status': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.post(url=BASE_URL + "/pet/1", params={'name': 'example', 'status': 'example'})
assert response.status_code == 401
def test_missing_petId(self):
"""Missing required param 'petId' — expects 400 or 422"""
response = requests.post(url=BASE_URL + "/pet/1", params={'name': 'example', 'status': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_invalid_types(self):
"""Invalid field types — expects 400 or 422"""
response = requests.post(url=BASE_URL + "/pet/1", params={'name': 'INVALID_TYPE_$$', 'status': 'INVALID_TYPE_$$'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/pet/1", params={'name': 'example', 'status': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}}
validate(instance=response.json(), schema=schema)
class TestDeletePet:
"""Tests for DELETE /pet/{petId}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.delete(url=BASE_URL + "/pet/1", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.delete(url=BASE_URL + "/pet/1")
assert response.status_code == 401
def test_missing_petId(self):
"""Missing required param 'petId' — expects 400 or 422"""
response = requests.delete(url=BASE_URL + "/pet/1", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
class TestUploadFile:
"""Tests for POST /pet/{petId}/uploadImage"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/pet/1/uploadImage", params={'additionalMetadata': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.post(url=BASE_URL + "/pet/1/uploadImage", params={'additionalMetadata': 'example'})
assert response.status_code == 401
def test_missing_petId(self):
"""Missing required param 'petId' — expects 400 or 422"""
response = requests.post(url=BASE_URL + "/pet/1/uploadImage", params={'additionalMetadata': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_invalid_types(self):
"""Invalid field types — expects 400 or 422"""
response = requests.post(url=BASE_URL + "/pet/1/uploadImage", params={'additionalMetadata': 'INVALID_TYPE_$$'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/pet/1/uploadImage", params={'additionalMetadata': 'example'}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'code': {'type': 'integer', 'format': 'int32'}, 'type': {'type': 'string'}, 'message': {'type': 'string'}}, 'xml': {'name': '##default'}}
validate(instance=response.json(), schema=schema)
class TestGetInventory:
"""Tests for GET /store/inventory"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/store/inventory", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 201, 204)
def test_missing_auth(self):
"""Missing auth token — expects 401"""
response = requests.get(url=BASE_URL + "/store/inventory")
assert response.status_code == 401
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/store/inventory", headers={"Authorization": "Bearer <YOUR_TOKEN>"})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'additionalProperties': {'type': 'integer', 'format': 'int32'}}
validate(instance=response.json(), schema=schema)
class TestPlaceOrder:
"""Tests for POST /store/order"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/store/order")
assert response.status_code in (200, 201, 204)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/store/order")
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'petId': {'type': 'integer', 'format': 'int64', 'example': 198772}, 'quantity': {'type': 'integer', 'format': 'int32', 'example': 7}, 'shipDate': {'type': 'string', 'format': 'date-time'}, 'status': {'type': 'string', 'description': 'Order Status', 'example': 'approved', 'enum': ['placed', 'approved', 'delivered']}, 'complete': {'type': 'boolean'}}, 'xml': {'name': 'order'}}
validate(instance=response.json(), schema=schema)
class TestGetOrderById:
"""Tests for GET /store/order/{orderId}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/store/order/1")
assert response.status_code in (200, 201, 204)
def test_missing_orderId(self):
"""Missing required param 'orderId' — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/store/order/1")
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/store/order/1")
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'petId': {'type': 'integer', 'format': 'int64', 'example': 198772}, 'quantity': {'type': 'integer', 'format': 'int32', 'example': 7}, 'shipDate': {'type': 'string', 'format': 'date-time'}, 'status': {'type': 'string', 'description': 'Order Status', 'example': 'approved', 'enum': ['placed', 'approved', 'delivered']}, 'complete': {'type': 'boolean'}}, 'xml': {'name': 'order'}}
validate(instance=response.json(), schema=schema)
class TestDeleteOrder:
"""Tests for DELETE /store/order/{orderId}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.delete(url=BASE_URL + "/store/order/1")
assert response.status_code in (200, 201, 204)
def test_missing_orderId(self):
"""Missing required param 'orderId' — expects 400 or 422"""
response = requests.delete(url=BASE_URL + "/store/order/1")
assert response.status_code in (400, 422)
class TestCreateUser:
"""Tests for POST /user"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/user")
assert response.status_code in (200, 201, 204)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/user")
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'username': {'type': 'string', 'example': 'theUser'}, 'firstName': {'type': 'string', 'example': 'John'}, 'lastName': {'type': 'string', 'example': 'James'}, 'email': {'type': 'string', 'example': 'john@email.com'}, 'password': {'type': 'string', 'example': '12345'}, 'phone': {'type': 'string', 'example': '12345'}, 'userStatus': {'type': 'integer', 'description': 'User Status', 'format': 'int32', 'example': 1}}, 'xml': {'name': 'user'}}
validate(instance=response.json(), schema=schema)
class TestCreateUsersWithListInput:
"""Tests for POST /user/createWithList"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.post(url=BASE_URL + "/user/createWithList")
assert response.status_code in (200, 201, 204)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.post(url=BASE_URL + "/user/createWithList")
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'username': {'type': 'string', 'example': 'theUser'}, 'firstName': {'type': 'string', 'example': 'John'}, 'lastName': {'type': 'string', 'example': 'James'}, 'email': {'type': 'string', 'example': 'john@email.com'}, 'password': {'type': 'string', 'example': '12345'}, 'phone': {'type': 'string', 'example': '12345'}, 'userStatus': {'type': 'integer', 'description': 'User Status', 'format': 'int32', 'example': 1}}, 'xml': {'name': 'user'}}
validate(instance=response.json(), schema=schema)
class TestLoginUser:
"""Tests for GET /user/login"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/user/login", params={'username': 'example', 'password': 'example'})
assert response.status_code in (200, 201, 204)
def test_invalid_types(self):
"""Invalid field types — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/user/login", params={'username': 'INVALID_TYPE_$$', 'password': 'INVALID_TYPE_$$'})
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/user/login", params={'username': 'example', 'password': 'example'})
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'string'}
validate(instance=response.json(), schema=schema)
class TestLogoutUser:
"""Tests for GET /user/logout"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/user/logout")
assert response.status_code in (200, 201, 204)
class TestGetUserByName:
"""Tests for GET /user/{username}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.get(url=BASE_URL + "/user/example")
assert response.status_code in (200, 201, 204)
def test_missing_username(self):
"""Missing required param 'username' — expects 400 or 422"""
response = requests.get(url=BASE_URL + "/user/example")
assert response.status_code in (400, 422)
def test_response_matches_schema(self):
"""Successful response body matches the documented schema"""
response = requests.get(url=BASE_URL + "/user/example")
if response.status_code not in (200, 201):
pytest.skip("no successful response to validate")
schema = {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'username': {'type': 'string', 'example': 'theUser'}, 'firstName': {'type': 'string', 'example': 'John'}, 'lastName': {'type': 'string', 'example': 'James'}, 'email': {'type': 'string', 'example': 'john@email.com'}, 'password': {'type': 'string', 'example': '12345'}, 'phone': {'type': 'string', 'example': '12345'}, 'userStatus': {'type': 'integer', 'description': 'User Status', 'format': 'int32', 'example': 1}}, 'xml': {'name': 'user'}}
validate(instance=response.json(), schema=schema)
class TestUpdateUser:
"""Tests for PUT /user/{username}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.put(url=BASE_URL + "/user/example")
assert response.status_code in (200, 201, 204)
def test_missing_username(self):
"""Missing required param 'username' — expects 400 or 422"""
response = requests.put(url=BASE_URL + "/user/example")
assert response.status_code in (400, 422)
class TestDeleteUser:
"""Tests for DELETE /user/{username}"""
def test_happy_path(self):
"""Happy path — expects 2xx response"""
response = requests.delete(url=BASE_URL + "/user/example")
assert response.status_code in (200, 201, 204)
def test_missing_username(self):
"""Missing required param 'username' — expects 400 or 422"""
response = requests.delete(url=BASE_URL + "/user/example")
assert response.status_code in (400, 422)
# ---- Multi-step flows: each test creates a resource and passes its id to the next calls ----
def _flow_value(body, path):
"""Read a value from a JSON body by key path (None when absent)."""
for key in path:
if not isinstance(body, dict) or key not in body:
return None
body = body[key]
return body
class TestUserFlow:
"""Multi-step flow /user: create → read → update → delete"""
def test_crud_flow(self):
created = requests.post(url=BASE_URL + "/user", json={'id': 10, 'username': 'theUser', 'firstName': 'John', 'lastName': 'James', 'email': 'john@email.com', 'password': '12345', 'phone': '12345', 'userStatus': 1})
assert created.status_code in (200, 201), created.text[:300]
try:
body = created.json()
except ValueError:
body = {}
item_id = _flow_value(body, ['username'])
if item_id is None:
pytest.skip("create response has no username field to pass to the next steps")
item_url = BASE_URL + "/user/" + str(item_id)
deleted = False
try:
response = requests.get(url=item_url)
assert response.status_code == 200, response.text[:300]
validate(instance=response.json(), schema={'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'username': {'type': 'string', 'example': 'theUser'}, 'firstName': {'type': 'string', 'example': 'John'}, 'lastName': {'type': 'string', 'example': 'James'}, 'email': {'type': 'string', 'example': 'john@email.com'}, 'password': {'type': 'string', 'example': '12345'}, 'phone': {'type': 'string', 'example': '12345'}, 'userStatus': {'type': 'integer', 'description': 'User Status', 'format': 'int32', 'example': 1}}, 'xml': {'name': 'user'}})
response = requests.put(url=item_url, json={'id': 10, 'username': 'theUser-updated', 'firstName': 'John', 'lastName': 'James', 'email': 'john@email.com', 'password': '12345', 'phone': '12345', 'userStatus': 1})
assert response.status_code in (200, 204), response.text[:300]
response = requests.delete(url=item_url)
assert response.status_code in (200, 202, 204), response.text[:300]
deleted = True
response = requests.get(url=item_url)
assert response.status_code in (404, 410), "deleted resource is still readable"
finally:
if not deleted: # leave no test data behind when a step fails
requests.delete(url=item_url)
class TestPetFlow:
"""Multi-step flow /pet: create → read → delete"""
def test_crud_flow(self):
created = requests.post(url=BASE_URL + "/pet", json={'name': 'doggie', 'photoUrls': [], 'id': 10}, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert created.status_code in (200, 201), created.text[:300]
try:
body = created.json()
except ValueError:
body = {}
item_id = _flow_value(body, ['id'])
if item_id is None:
pytest.skip("create response has no id field to pass to the next steps")
item_url = BASE_URL + "/pet/" + str(item_id)
deleted = False
try:
response = requests.get(url=item_url, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code == 200, response.text[:300]
validate(instance=response.json(), schema={'required': ['name', 'photoUrls'], 'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'name': {'type': 'string', 'example': 'doggie'}, 'category': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 1}, 'name': {'type': 'string', 'example': 'Dogs'}}, 'xml': {'name': 'category'}}, 'photoUrls': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'string', 'xml': {'name': 'photoUrl'}}}, 'tags': {'type': 'array', 'xml': {'wrapped': True}, 'items': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string'}}, 'xml': {'name': 'tag'}}}, 'status': {'type': 'string', 'description': 'pet status in the store', 'enum': ['available', 'pending', 'sold']}}, 'xml': {'name': 'pet'}})
response = requests.delete(url=item_url, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (200, 202, 204), response.text[:300]
deleted = True
response = requests.get(url=item_url, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
assert response.status_code in (404, 410), "deleted resource is still readable"
finally:
if not deleted: # leave no test data behind when a step fails
requests.delete(url=item_url, headers={"Authorization": "Bearer <YOUR_TOKEN>"})
class TestOrderFlow:
"""Multi-step flow /store/order: create → read → delete"""
def test_crud_flow(self):
created = requests.post(url=BASE_URL + "/store/order", json={'id': 10, 'petId': 198772, 'quantity': 7, 'status': 'approved'})
assert created.status_code in (200, 201), created.text[:300]
try:
body = created.json()
except ValueError:
body = {}
item_id = _flow_value(body, ['id'])
if item_id is None:
pytest.skip("create response has no id field to pass to the next steps")
item_url = BASE_URL + "/store/order/" + str(item_id)
deleted = False
try:
response = requests.get(url=item_url)
assert response.status_code == 200, response.text[:300]
validate(instance=response.json(), schema={'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64', 'example': 10}, 'petId': {'type': 'integer', 'format': 'int64', 'example': 198772}, 'quantity': {'type': 'integer', 'format': 'int32', 'example': 7}, 'shipDate': {'type': 'string', 'format': 'date-time'}, 'status': {'type': 'string', 'description': 'Order Status', 'example': 'approved', 'enum': ['placed', 'approved', 'delivered']}, 'complete': {'type': 'boolean'}}, 'xml': {'name': 'order'}})
response = requests.delete(url=item_url)
assert response.status_code in (200, 202, 204), response.text[:300]
deleted = True
response = requests.get(url=item_url)
assert response.status_code in (404, 410), "deleted resource is still readable"
finally:
if not deleted: # leave no test data behind when a step fails
requests.delete(url=item_url)
Built by Arsen, an independent developer. Free for 5 generations a day; Pro adds Playwright and Schemathesis runners, CI workflow export and a ready-to-run project. Pricing