Skip to main content

Contract-driven service interaction modeling and test generation.

Project description

Surety
PyPI version Python versions Tests Documentation Status License

Contract-driven testing for Python.

Surety makes contract-based testing simple and readable.

The surety framework replaces scattered assertions with explicit contracts — Python classes that define expected data structures, generate realistic test data, and validate real responses deterministically.

from surety import Dictionary, String, Int, Bool

class CustomerContract(Dictionary):
    Id = Int(name='customer_id', min_val=1000, max_val=99999)
    Email = String(name='email')
    FirstName = String(name='first_name')
    Active = Bool(name='active')

customer = CustomerContract()
print(customer.value)
# {'customer_id': 48271, 'email': 'jane.doe@example.com', 'first_name': 'Margaret', 'active': True}

Features

  • Contract-first — define expected behavior as reusable Python classes, not scattered assertions

  • Data generation — auto-generate realistic test data using Faker with 80+ providers

  • Transport-agnostic — the same contract validates API responses, database records, and UI state

  • Structured diffs — precise mismatch reporting with custom comparison rules (via surety-diff)

  • API testing — HTTP interaction, schema-based mocking, and request verification (via surety-api)

  • Database testing — PostgreSQL, MySQL, SQLite, and Cassandra support (via surety-db)

  • Field typesBool, Int, Float, Decimal, String, Uuid, DateTime, Enum, Array, and more

  • Extensible — create custom field types, comparison rules, and execution adapters

  • Python 3.7+ compatible

Install

pip install surety

Optional extensions:

pip install surety-diff      # Structured comparison engine
pip install surety-api       # HTTP API interaction and mocking
pip install surety-db        # Database interaction layer
pip install surety-config    # YAML-based configuration

Quick Example

Define a contract, generate data, and validate:

from surety import Dictionary, String, Int, Array
from surety.diff import compare

# Define contracts
class AddressContract(Dictionary):
    City = String(name='city')
    ZipCode = String(name='zip_code', fake_as='zipcode')

class OrderContract(Dictionary):
    Id = Int(name='order_id')
    Status = String(name='status', default='pending')
    ShippingAddress = AddressContract(name='shipping_address')

# Generate test data
order = OrderContract()
print(order.value)
# {'order_id': 7312, 'status': 'pending', 'shipping_address': {'city': 'Portland', 'zip_code': '97201'}}

# Validate against actual response
compare(actual=api_response, expected=order.value)

Override specific values while keeping the rest auto-generated:

order = OrderContract().with_values({
    Order.Id.name: 1,
    Order.ShippingAddress.name: {AddressContract.City.name: 'Seattle'}
})

Use comparison rules for dynamic fields:

from surety.diff import compare
from surety.diff.rules import has_some_value, timestamp_equal_with_delta_3s

compare(
    actual=response,
    expected=order.value,
    rules={
        Order.Id.name: has_some_value,
        Order.CreatedAt.name: timestamp_equal_with_delta_3s
    }
)

Architecture

Surety separates three concerns:

Contracts

surety

Define expectations and generate test data

Execution

surety-api, surety-db

Perform HTTP and database interactions

Validation

surety-diff

Compare actual data against contracts

Documentation

Full documentation: https://surety.readthedocs.io/

Issues

Report bugs and feature requests at the issue tracker.

License

MIT License. See LICENSE for details.

Copyright (c) 2026 Elena Kulgavaya.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

surety-0.0.5.tar.gz (283.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

surety-0.0.5-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file surety-0.0.5.tar.gz.

File metadata

  • Download URL: surety-0.0.5.tar.gz
  • Upload date:
  • Size: 283.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surety-0.0.5.tar.gz
Algorithm Hash digest
SHA256 beaa527a5ed50d28146e1a6f3d420fa2efcc9ed1e51b336c5c9f2a44023d0ae5
MD5 0c097bd063532ca168f159cda48d9af7
BLAKE2b-256 3ae2d5c858be3edfb90cf62ee3ab0b7094fe6e81734c253f36bb16388032456c

See more details on using hashes here.

File details

Details for the file surety-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: surety-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surety-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 b48299bdeca0984f7b79f1026f5986251a192449956f173149a4d1c5d9414b0f
MD5 cfa553ae5e8e977ef1cada28ec72634d
BLAKE2b-256 51d83bc6b18a799995907da04ff01be7ad94f6fa90e7559c9854626a98d6787b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page