Skip to main content

Every call recorded. Every field asserted. Zero guesswork.

Project description

bigfoot

CI PyPI Python 3.11+ License: MIT

Every call recorded. Every field asserted. Zero guesswork.

bigfoot intercepts every external call your code makes -- HTTP, subprocess, database, socket, Redis, SMTP, WebSocket, logging -- and forces your tests to account for all of them. Forget to assert an interaction? Test fails. Register a mock that never fires? Test fails. Make a call you didn't mock? Test fails immediately.

pip install bigfoot[all]

Quick Start

import bigfoot
import httpx
from dirty_equals import IsInstance

def test_payment_flow():
    bigfoot.http.mock_response("POST", "https://api.stripe.com/v1/charges",
                               json={"id": "ch_123"}, status=200)

    with bigfoot:
        response = httpx.post("https://api.stripe.com/v1/charges",
                              json={"amount": 5000})

    bigfoot.http.assert_request(
        method="POST", url="https://api.stripe.com/v1/charges",
        headers=IsInstance(dict), body=IsInstance(str),
    )
    assert response.json()["id"] == "ch_123"

If you forget the assert_request() call, bigfoot fails the test at teardown:

E   bigfoot._errors.UnassertedInteractionsError: 1 interaction(s) were not asserted
E
E     [sequence=0] [HttpPlugin] POST https://api.stripe.com/v1/charges (status=200)
E       To assert this interaction:
E         verifier.assert_interaction(
E       http.request,
E       method="POST",
E       url="https://api.stripe.com/v1/charges",
E       request_headers={'host': 'api.stripe.com', ...},
E       request_body='{"amount":5000}',
E       status=200,
E       response_headers={'content-type': 'application/json'},
E       response_body='{"id": "ch_123"}',
E   )

Every field is shown. Every value is real. Copy, paste, done.

How It Works

  1. Register mocks before the sandbox (mock_response, mock_run, returns, etc.)
  2. Open the sandbox with with bigfoot: (or async with bigfoot:)
  3. Code runs normally inside the sandbox, but external calls are intercepted and recorded
  4. Assert interactions after the sandbox closes, in order
  5. verify_all() runs automatically at test teardown via the pytest plugin

No fixture injection required. Install bigfoot, import bigfoot, and go.

Plugins

bigfoot ships with 14 plugins covering the most common external dependencies:

Category Plugins Intercepts
General MockPlugin, LoggingPlugin Named mock proxies, logging module
HTTP HttpPlugin httpx, requests, urllib, aiohttp
Subprocess SubprocessPlugin, PopenPlugin, AsyncSubprocessPlugin subprocess.run, shutil.which, Popen, asyncio.create_subprocess_*
Database DatabasePlugin, Psycopg2Plugin, AsyncpgPlugin sqlite3, psycopg2, asyncpg
Network SmtpPlugin, SocketPlugin, RedisPlugin, WebSocket smtplib, socket, redis, websockets, websocket-client
Plugin examples

Subprocess

bigfoot.subprocess_mock.mock_run(["git", "pull"], returncode=0, stdout="Up to date.\n")

Database (sqlite3)

bigfoot.db_mock.new_session() \
    .expect("connect", returns=None) \
    .expect("execute", returns=[]) \
    .expect("commit", returns=None) \
    .expect("close", returns=None)

Redis

bigfoot.redis_mock.mock_command("GET", returns=b"cached_value")

SMTP

bigfoot.smtp_mock.new_session() \
    .expect("connect", returns=(220, b"OK")) \
    .expect("ehlo", returns=(250, b"OK")) \
    .expect("sendmail", returns={}) \
    .expect("quit", returns=(221, b"Bye"))

Logging

bigfoot.log_mock.assert_info("User logged in", "myapp")

Mock (general)

svc = bigfoot.mock("PaymentService")
svc.charge.returns({"status": "ok"})

Advanced Features

Concurrent assertions -- relax FIFO ordering for parallel requests:

with bigfoot.in_any_order():
    bigfoot.http.assert_request(method="GET", url=".../a", headers=IsInstance(dict), body=None)
    bigfoot.http.assert_request(method="GET", url=".../b", headers=IsInstance(dict), body=None)

Spy / pass-through -- delegate to the real object, still record and require assertion:

bigfoot.spy("Name", real_obj)
bigfoot.http.pass_through("GET", url)

Configuration via pyproject.toml:

[tool.bigfoot.http]
require_response = true  # Every assert_request() must be followed by .assert_response()

Per-call arguments override project-level settings. See the configuration guide.

Selective Installation

bigfoot[all] installs everything. For a smaller footprint, pick only what you need:

pip install bigfoot                       # Core plugins (no optional deps)
pip install bigfoot[http]                 # + httpx, requests, urllib
pip install bigfoot[aiohttp]              # + aiohttp
pip install bigfoot[psycopg2]             # + PostgreSQL (psycopg2)
pip install bigfoot[asyncpg]              # + PostgreSQL (asyncpg)
pip install bigfoot[websockets]           # + async WebSocket
pip install bigfoot[websocket-client]     # + sync WebSocket
pip install bigfoot[redis]                # + Redis
pip install bigfoot[matchers]             # + dirty-equals matchers

Documentation

Full API reference, plugin guides, and advanced usage: axiomantic.github.io/bigfoot

License

MIT

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

bigfoot-0.11.1.tar.gz (209.0 kB view details)

Uploaded Source

Built Distribution

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

bigfoot-0.11.1-py3-none-any.whl (78.3 kB view details)

Uploaded Python 3

File details

Details for the file bigfoot-0.11.1.tar.gz.

File metadata

  • Download URL: bigfoot-0.11.1.tar.gz
  • Upload date:
  • Size: 209.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bigfoot-0.11.1.tar.gz
Algorithm Hash digest
SHA256 08e10d2be0c4661222be02d786938d0e76ad5a9056c6b0d13d476416df283a08
MD5 c0b291658d787193f538a49aaf23a374
BLAKE2b-256 f6e8a61ddb64796539213ba4149336a7c32ce38b10d6d06547c0481504c8a466

See more details on using hashes here.

Provenance

The following attestation bundles were made for bigfoot-0.11.1.tar.gz:

Publisher: release.yml on axiomantic/bigfoot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bigfoot-0.11.1-py3-none-any.whl.

File metadata

  • Download URL: bigfoot-0.11.1-py3-none-any.whl
  • Upload date:
  • Size: 78.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bigfoot-0.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 00873e241bf4f995ba68eded5d743d862512484a8c4a50e00a199851be05658f
MD5 1bfda3855f502e58a224da841d129899
BLAKE2b-256 1896e0124588ec225ad36dac88a3f4e85ee38bd114e693039be48d78bfa39e99

See more details on using hashes here.

Provenance

The following attestation bundles were made for bigfoot-0.11.1-py3-none-any.whl:

Publisher: release.yml on axiomantic/bigfoot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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