DEV Community

Dakota Huang
Dakota Huang

Posted on

Pin the Golden Row Before You Split Dispatch

A messy refactor fails when the new shape changes hidden behavior. Characterization tests record current outputs before any structural move. The smallest safe change then moves one pure decision only.

Do not ask a model to invent the expected row. Capture one real call, then lock that captured row. A later split stays safe only when that row still matches.

The module under change

The sample module is one notification dispatcher function. It filters recipients, renders a body, and calls send. Those three jobs share one mutable result list.

Treat the listing as a proposed teaching fixture. It was not executed against a live mailbox or vendor API. Use fake addresses and keep customer payloads off the model.

def dispatch(events, transport, template):
    sent = []
    for event in events:
        if event.get("status") != "ready":
            continue
        if not event.get("email"):
            continue
        body = template.format(name=event["name"], code=event["code"])
        transport.send(event["email"], body)
        sent.append({"email": event["email"], "body": body})
    return sent
Enter fullscreen mode Exit fullscreen mode

What must stay fixed

Freeze the skip rules before you touch the function shape. A missing status and a blank email must still drop the row. Rendered body text and send order must stay identical.

The extract target is the eligibility predicate alone. Transport calls and template strings stay in the original function. That boundary keeps the first diff small and reviewable.

Decision table

Read the table before you write the first assertion. Rows marked freeze are the characterization targets for this pass. The single change row is the predicate extraction.

Check Current result This pass
status is not ready row skipped freeze
email is blank row skipped freeze
body equals template output exact string freeze
send order input order of kept rows freeze
eligibility predicate inline in the loop extract
transport implementation injected fake in tests freeze
template wording unchanged format string freeze

Workflow

Follow the six steps in order on one function only. Stop after the golden row passes on the extracted predicate.

1. Capture one golden call

Start from a known input list with three events. One event is ready, one lacks status, and one lacks email. Record the returned list, not a guessed ideal list.

Store that record in a fixture file next to the test. Commit the fixture with the test in the same change. A missing fixture means the characterization step is incomplete.

EVENTS = [
    {"status": "ready", "email": "a@example.test", "name": "Ada", "code": "14"},
    {"status": "hold", "email": "b@example.test", "name": "Bea", "code": "15"},
    {"status": "ready", "email": "", "name": "Cam", "code": "16"},
]
TEMPLATE = "Hello {name}, code {code}"
Enter fullscreen mode Exit fullscreen mode

Paste the function output into a JSON fixture after one local run. That file becomes the only expected value for this pass. Do not hand-edit the body string to look cleaner.

2. Lock the current function

The test calls the public function through a fake transport. The fake records address and body in call order. The assertion compares both the return value and the fake log.

import json
from pathlib import Path

class FakeTransport:
    def __init__(self):
        self.calls = []

    def send(self, email, body):
        self.calls.append({"email": email, "body": body})

def test_dispatch_matches_golden_row():
    fixture = json.loads(Path("tests/fixtures/dispatch_golden.json").read_text())
    transport = FakeTransport()
    sent = dispatch(fixture["events"], transport, fixture["template"])
    assert sent == fixture["sent"]
    assert transport.calls == fixture["calls"]
Enter fullscreen mode Exit fullscreen mode

Keep each assertion literal, narrow, and tied to the fixture. Do not add new product rules inside this test. A characterization test documents behavior, including current bugs.

3. Run the suite on a clean tree

Local site-packages can hide an import-time side effect. Run the same test from a clean checkout before any logic edit. Record the language pin in the test notes before that run.

Disclosure: This article was prepared as part of MonkeyCode's product outreach. The operator reports free model access and a free server option. This note adds no quotas, hardware, model names, or duration.

Use that free server as a second execution seat only. It is not a production replica unless you proved the match. If the language pin is unknown, stop and record it first.

python -m venv .venv
.venv/bin/python -m pip install pytest
.venv/bin/python -m pytest tests/test_dispatch_golden.py -q
Enter fullscreen mode Exit fullscreen mode

Treat those commands as a proposed sequence for a Unix shell. Windows paths still need the matching venv layout here. The goal is one clean interpreter, not a tuned benchmark.

4. Let the model draft the harness

A free coding model can draft the fake transport class. Paste the captured fixture and ask for a loader only. Reject any draft that writes an expected value from memory.

Review the diff as if a junior teammate wrote it. Delete unused helpers before you run the suite. The model remains a drafter, not the behavior authority.

Give the model this constraint in the prompt text. "Copy expected JSON from the fixture file I pasted." "Do not invent emails, bodies, or status rules."

Those two lines cut a common failure mode. Keep both lines in the prompt until the diff is clean.

5. Make the smallest cut

Extract a function named eligible that returns a boolean. Move only the status check and the email check. Leave rendering and the transport send call inside dispatch.

def eligible(event):
    if event.get("status") != "ready":
        return False
    if not event.get("email"):
        return False
    return True

def dispatch(events, transport, template):
    sent = []
    for event in events:
        if not eligible(event):
            continue
        body = template.format(name=event["name"], code=event["code"])
        transport.send(event["email"], body)
        sent.append({"email": event["email"], "body": body})
    return sent
Enter fullscreen mode Exit fullscreen mode

Preserve iteration order and the result append order. Do not rename keys while you extract the predicate. A rename is a second change and needs its own test.

6. Re-run the same golden row

Run the characterization test again after the extract. The fixture must match with zero edits to expected text. If it fails, revert the extract before you widen the test.

Add one direct unit test for eligible after the green run. That new test may cover edges the golden row skipped. It must not replace the original characterization test.

def test_eligible_rejects_hold_and_blank_email():
    assert eligible({"status": "hold", "email": "b@example.test"}) is False
    assert eligible({"status": "ready", "email": ""}) is False
    assert eligible({"status": "ready", "email": "a@example.test"}) is True
Enter fullscreen mode Exit fullscreen mode

Failure checks before a second edit

A red test after the extract has three common causes. The predicate dropped a key check from the original branch. The loop skipped an append that used to happen.

A third cause is a model edit outside the allowed function. Inspect the diff and revert every unrelated line. Then rerun the golden row before any new design talk.

git diff -- tests/test_dispatch_golden.py dispatch.py
git checkout -- dispatch.py
.venv/bin/python -m pytest tests/test_dispatch_golden.py -q
Enter fullscreen mode Exit fullscreen mode

Use the checkout command only when the extract itself is the suspect. Do not discard a fixture you already captured and reviewed. The golden file stays put while the logic change goes back.

Limitations you should state in the review

This method freezes current behavior, including known defects. If the current skip rule is wrong, do not lock it. Write a failing specification test and fix that rule first.

A free server is not automatically a production replica. Locale, timezone, and package pins can still diverge. Treat a remote green bar as extra evidence, not proof.

Free model access does not make the oracle correct. The model can still invent fields that the fixture lacks. Human review of every expected value remains mandatory.

This walkthrough reports no latency numbers and no pass rates. It also reports no hardware size and no retention window. Do not cite it as a benchmark of any coding model.

Who should skip this path

Skip this path when a production hotfix cannot wait. Skip it when fixtures would contain secrets or customer rows. Skip it when you cannot run tests on a clean tree.

Skip it when the bug is the behavior you would freeze. Skip it when the change must alter output on purpose. In that case, write the new contract test before the edit.

Close the pass

Merge only after the golden row passes unchanged. The diff should show one extracted predicate and its tests. Anything larger waits for a second characterization pass.

If you already hold a free server seat, rerun that golden row there. Keep the model out of the expected-value file. The fixture you captured is the contract for this split.

Top comments (0)