Wrap the real call
Substitution lies in a particular way.
A MagicMock answers every method,
records a flat list, and never runs the
code you claimed to test. Self-calls
vanish because the substitute is not
the object. You can get a green suite
that never saw the gateway timeout
propagate, never saw the ledger skip a
write, never saw
charge(500) and
charge(amount=500) as the
same call. wrapture’s claim is that
testing and tracing wanted the same
primitive all along: sit on the live
callable without disturbing it, then
choose to watch, change, or answer.
The tape is the call graph as it
actually ran. That is a different
oracle than “the mock was touched.”
The same geometry shows up when the
agent writes the library. Graham did
not prompt once and hope. He spent
days on design docs, then opened one
layer at a time, and he made the docs
fail when the examples drifted —
doctests, not a README that rot. The
late move is the one to steal: take
someone else’s real test suite and
force your new tool to express it.
Every awkward mapping is either a
principle you should write down or a
hole you should fill. That is directed
generation. The AI types. The human
who already knows the corner of the
language owns the shape, the refusals,
and the moment a layer is allowed to
start.
Do not confuse this with skipping
review. Taste, product intent, and
whether this wrapper should exist at
all stay human. Repetitive correctness
— did the timeout skip the ledger, did
the example still run, did the patch
get removed — can sit on the wrap and
the doctest. Humans are not
unnecessary. Line-by-line reading of
agent output is the wrong bottleneck
once the design is specified and the
tape can fail. Shared misunderstandings
still leak: if you and the agent both
think a Mock is a wrap, you will ship
a fabricated object and call it
observation. Stop condition: when the
bindings cover the graph you care
about, leftover patches are swept, and
a real foreign test suite has been
expressed, stop hunting for one more
mock to replace. A new class of
collaborator needs a new binding.
Otherwise you are nerd-sniping the
harness.
Checklist
-
If the callable exists, wrap it.
Invented objects still belong to
unittest.mock.
-
Assert on the nested tape (who called
whom, real returns, injected
failures), not on a flat mock call
list.
-
Apply and remove bindings as a unit.
Sweep leftover patches in the test
runner.
-
Design docs before the first agent
commit. One layer at a time. Doctest
every example.
-
Port one real foreign test suite onto
the new tool. Friction is a decision,
not a shrug.
This week: pick one test that patches
a live collaborator with MagicMock.
Wrap the real method, inject one
failure, and assert the side effect
that should not have happened.