SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
3.6 KB · 121 lines markdown
Rendered Raw Blame History
1<!--2Author: Simon-Pierre Boucher3Contact: contact@spboucher.ai4-->56# Patterns — Testing Backend Services78## Contents9- Testcontainers setup (pytest + Postgres)10- Per-test isolation via transaction rollback11- Polling instead of sleeping12- Frozen clock and seeded randomness13- Data factories14- Contract test sketch15- Gotchas1617## Testcontainers setup (pytest + Postgres)1819```python20# pip install testcontainers[postgres] pytest21import pytest22from testcontainers.postgres import PostgresContainer2324@pytest.fixture(scope="session")25def pg_url():26    # One container per session: startup (~2-5s) is paid once, not per test.27    with PostgresContainer("postgres:17") as pg:28        yield pg.get_connection_url()29```3031## Per-test isolation via transaction rollback3233```python34@pytest.fixture35def db(pg_url):36    engine = get_engine(pg_url)37    conn = engine.connect()38    tx = conn.begin()39    yield conn          # test runs inside the transaction40    tx.rollback()       # everything the test wrote vanishes41    conn.close()42```4344Escape hatch: code under test that commits internally needs per-test schemas45(`CREATE SCHEMA test_{uuid}`) instead of rollback.4647## Polling instead of sleeping4849```python50import time5152def wait_until(predicate, timeout=5.0, interval=0.05):53    # 50ms interval: fast feedback without hammering; 5s cap: fail loudly.54    deadline = time.monotonic() + timeout55    while time.monotonic() < deadline:56        if predicate():57            return58        time.sleep(interval)59    raise AssertionError(f"condition not met within {timeout}s")6061publish(event)62wait_until(lambda: repo.count(status="processed") == 1)63```6465## Frozen clock and seeded randomness6667```python68# pip install freezegun69from freezegun import freeze_time7071@freeze_time("2026-08-05T12:00:00Z")72def test_subscription_expires():73    sub = make_subscription(days=30)74    assert sub.expires_at == datetime(2026, 9, 4, 12, tzinfo=UTC)7576# conftest.py — same failures every run77import random78random.seed(1337)79```8081## Data factories8283```python84import itertools85_seq = itertools.count()8687def make_user(**over):88    n = next(_seq)89    defaults = dict(email=f"u{n}@test.local", name=f"User {n}", plan="free")90    return User(**{**defaults, **over})9192def make_order(user=None, **over):93    user = user or make_user()94    defaults = dict(user_id=user.id, total_cents=1000, status="pending")95    return Order(**{**defaults, **over})96```9798Unique-per-call defaults keep parallel tests from colliding on unique constraints.99100## Contract test sketch101102Consumer publishes expectations; provider CI verifies against the real app:103104```python105# consumer side (pact-python): "GET /users/9 returns id+email"106pact.given("user 9 exists").upon_receiving("get user") \107    .with_request("GET", "/users/9") \108    .will_respond_with(200, body={"id": 9, "email": Like("a@b.c")})109```110111Lighter alternative: validate provider responses in integration tests against112the OpenAPI schema (`schemathesis` or response-validation middleware).113114## Gotchas115- Mock-heavy tests rot: they keep passing while real integration breaks — the DB mock never raises `UniqueViolation`.116- `scope="session"` containers + tests that commit = cross-test contamination; pair session containers with rollback/schema isolation.117- Asserting exact timestamps or auto-increment IDs couples tests to execution order.118- Parallel runners (pytest-xdist) expose hidden shared state — fixed ports, `/tmp` paths, same S3 bucket keys.119- A retried-until-green test is a deleted test with extra steps; fix the race instead of adding `--reruns`.120- E2E through the public API only — reaching into another service's DB in a test welds the deploy order together.121