Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions python-test-samples/schema-and-contract-testing/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![python: 3.9](https://img.shields.io/badge/Python-3.9-green)](https://img.shields.io/badge/Python-3.11-green)
[![python: 3.13](https://img.shields.io/badge/Python-3.13-green)](https://img.shields.io/badge/Python-3.13-green)
[![test: unit](https://img.shields.io/badge/Test-Unit-blue)](https://img.shields.io/badge/Test-Unit-blue)

# Python: Schema and Contract Testing for Event-Driven Architectures
Expand Down Expand Up @@ -116,7 +116,7 @@ In order to detect breaking changes using schema testing, we will generate an ev
Create a virtual environment and install the dependencies.

```shell
python3 -m venv .venv
python3 -m virtualenv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
iniconfig==2.0.0
packaging==23.1
pluggy==1.0.0
pydantic==1.10.13
pytest==7.3.1
typing_extensions==4.5.0
pydantic>=2.5.0
pytest>=7.4.0
typing-extensions>=4.8.0
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from __future__ import annotations

from pydantic import BaseModel, Field, validator
from pydantic import BaseModel, Field, field_validator


class Customer(BaseModel):
Expand All @@ -17,9 +17,10 @@ class Customer(BaseModel):
..., examples=['2 Park St, Sydney, NSW 2000, Australia'], title='Address'
)

@validator('address')
def address_has_four_fields(cls, address_value):
"""Fucntion to validate address field"""
if len(address_value.split(',')) != 4:
@field_validator('address', mode='before')
@classmethod
def address_has_four_fields(cls, address_value: str) -> str:
"""Function to validate address field"""
if isinstance(address_value, str) and len(address_value.split(',')) != 4:
raise ValueError("Address must have four fields separated by ','.")
return address_value
return address_value
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
import json
import pytest
from pydantic import ValidationError
from tests.context import ConsumerCustomerModel
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

def instantiate_customer(schema_version):
"""utility method to instantiate customer model with business alidations"""
sample_event_file = f"events/customerCreated-event-{schema_version}.json"
with open(sample_event_file, "r", encoding="utf-8") as event:
new_schema_event = json.load(event)
return ConsumerCustomerModel(**new_schema_event)
from __future__ import annotations

from pydantic import BaseModel, Field, field_validator

def test_address_with_four_fields_compatible_with_business_logic():
"""
business validation for address field checks for 4 fields separated by ","
event generated with schema 1.1.0 satisfies this, so test passes
"""
customer = instantiate_customer("1.1.0")
assert customer.address == "2 Park St, Sydney, NSW 2000, Australia", "Full address compatible"

class Customer(BaseModel):
"""Class representing a customer"""
customerId: str = Field(
..., examples=['577af109-1f19-4d0a-9c56-359f44ca0034'], title='Customerid'
)
firstName: str = Field(..., examples=['Jane'], title='Firstname')
lastName: str = Field(..., examples=['Doe'], title='Lastname')
address: str = Field(
..., examples=['2 Park St, Sydney, NSW 2000, Australia'], title='Address'
)

def test_street_name_for_address_not_compatible_with_business_logic():
"""
business validation for address field checks for 4 fields separated by ","
event generated with schema 1.4.0 does not satisfy this, so test fails
"""
with pytest.raises(Exception) as e_info:
customer = instantiate_customer("1.4.0")
assert e_info.type == ValidationError
assert "Address must have four fields separated by ','" in str(
e_info.value)
@field_validator('address')
@classmethod
def address_has_four_fields(cls, address_value: str) -> str:
"""Function to validate address field"""
if len(address_value.split(',')) != 4:
raise ValueError("Address must have four fields separated by ','.")
return address_value
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ def test_removing_required_element_not_backward_compatible():
with pytest.raises(Exception) as e_info:
customer = instantiate_customer("1.3.0")
assert e_info.type == ValidationError
assert "field required" in str(e_info.value)
assert "firstName" in str(e_info.value)
assert "lastName" in str(e_info.value)
# Updated for Pydantic v2 error message format
error_message = str(e_info.value)
assert "Field required" in error_message # Pydantic v2 uses "Field required"
assert "firstName" in error_message
assert "lastName" in error_message


def test_changing_business_logic_existing_field_backward_compatible():
Expand All @@ -54,4 +56,4 @@ def test_changing_business_logic_existing_field_backward_compatible():
test passes
"""
customer = instantiate_customer("1.4.0")
assert customer.address == "2 Park St", "Street address not breaking schema change"
assert customer.address == "2 Park St", "Street address not breaking schema change"