Skip to content

pytest Integration

bigfoot integrates with pytest automatically via the pytest11 entry point. No conftest.py changes are required. Install bigfoot and every test gets a fresh verifier with automatic teardown verification.

Module-level API (preferred)

The simplest way to use bigfoot is to import bigfoot and call module-level functions directly:

import bigfoot

def test_example():
    email = bigfoot.mock("EmailService")
    email.send.returns(True)

    with bigfoot:
        email.send(to="user@example.com")

    bigfoot.assert_interaction(email.send)
    # verify_all() is called automatically at teardown

with bigfoot: is shorthand for with bigfoot.sandbox():. Both return the active StrictVerifier from __enter__, so with bigfoot as v: gives you the verifier directly if you need it. bigfoot.sandbox() remains available as the explicit form for cases where you need to pass the context manager around.

Behind the scenes, an autouse fixture creates one StrictVerifier per test, stores it in a ContextVar, and calls verify_all() after the test completes.

Async tests

bigfoot and bigfoot.in_any_order() both support async with. Use pytest-asyncio for async test functions:

import bigfoot
import httpx

async def test_async_http():
    bigfoot.http.mock_response("GET", "https://api.example.com/items", json={"items": []})

    async with bigfoot:
        async with httpx.AsyncClient() as client:
            response = await client.get("https://api.example.com/items")
        assert response.json() == {"items": []}

    bigfoot.assert_interaction(bigfoot.http.request, method="GET")
    # verify_all() called at teardown

Using bigfoot.http

bigfoot.http is a proxy to the HttpPlugin for the current test. It auto-creates the plugin on first access, so no explicit instantiation is needed:

import bigfoot
import requests

def test_api_call():
    bigfoot.http.mock_response("POST", "https://api.example.com/users",
                               json={"id": 42}, status=201)

    with bigfoot:
        response = requests.post("https://api.example.com/users", json={"name": "Alice"})
        assert response.status_code == 201
        assert response.json()["id"] == 42

    bigfoot.assert_interaction(
        bigfoot.http.request,
        method="POST",
        url="https://api.example.com/users",
        status=201,
    )

Teardown behavior

verify_all() is called after the test function returns (or raises). If the test fails with an assertion error mid-way, verify_all() still runs. If both the test assertion and verify_all() fail, pytest reports both errors.

bigfoot_verifier fixture (escape hatch)

When you need direct access to the StrictVerifier object, inject the bigfoot_verifier fixture. It returns the same verifier that the module-level API uses for that test:

from bigfoot import StrictVerifier

def test_with_fixture(bigfoot_verifier: StrictVerifier):
    email = bigfoot_verifier.mock("EmailService")
    email.send.returns(True)

    with bigfoot_verifier.sandbox():
        email.send(to="user@example.com")

    bigfoot_verifier.assert_interaction(email.send)
    # verify_all() called automatically at teardown

You can also mix styles within the same test:

import bigfoot
from bigfoot import StrictVerifier

def test_mixed(bigfoot_verifier: StrictVerifier):
    email = bigfoot.mock("EmailService")  # same verifier
    email.send.returns(True)

    with bigfoot:
        email.send(to="user@example.com")

    assert bigfoot.current_verifier() is bigfoot_verifier  # True
    bigfoot.assert_interaction(email.send)

Manual StrictVerifier

If you need a verifier outside of pytest (e.g., in a script or custom test runner), create one manually and call verify_all() yourself:

from bigfoot import StrictVerifier

def test_manual():
    verifier = StrictVerifier()
    try:
        email = verifier.mock("EmailService")
        email.send.returns(True)

        with verifier.sandbox():
            email.send(to="user@example.com")

        verifier.assert_interaction(email.send)
    finally:
        verifier.verify_all()

The try/finally ensures verify_all() runs even if assertions fail.