Contents

Engineering Craft › Testing

Test Data Builder / Factory

Helpers that create valid test objects with sensible defaults.

Also known as: test factory, object mother, builder pattern for tests

A test data builder is a helper that creates valid objects for tests, with sensible defaults. A test states only the fields it cares about, and the builder fills in the rest with values that make the object valid. The same idea is called a factory in some libraries.

from dataclasses import dataclass, replace

@dataclass(frozen=True)
class Order:
    total: int = 50
    express: bool = False
    zone: str = "local"

def make_order(**overrides):
    return replace(Order(), **overrides)

def test_express_orders_cost_more():
    order = make_order(express=True, total=120)
    assert order.express and order.total == 120

The test reads as “an express order worth 120”, with no noise about other fields. When the object gains a required field, you update the builder in one place rather than every test.

The trade-off is hidden defaults. A reader has to look at the builder to know what a test is really using, and a default that makes the object quietly valid may hide a case the test should cover. Builders also add code to maintain.

The classic mistake is letting defaults carry meaning. If a test depends on the default zone being local, set it explicitly, so a change to the default doesn’t break an unrelated test in a confusing way. Keep defaults neutral and valid, and state anything the test depends on. For tests that need real persisted data, see test databases.