Skip to content
Back to skills

Builder Rules

ASecurity

Rules for building test data in Python with factory_boy: explicit values for everything a test asserts on, keyword overrides and Traits, build() versus create(), resetting sequences. Use when creating or using a factory in a Python test. Background knowledge that agents preload; not a command.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 11, 2026
developmentpythondatabase

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned November 11, 2026

npx -y skills add JanSzewczyk/claude-plugins --skill builder-rules --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Builder Rules?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Builder Rules
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/janszewczyk-builder-rules/badge)](https://www.skillsdirectory.com/skills/janszewczyk-builder-rules)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: builder-rules
description: "Rules for building test data in Python with factory_boy: explicit values for everything a test asserts on, keyword overrides and Traits, build() versus create(), resetting sequences. Use when creating or using a factory in a Python test. Background knowledge that agents preload; not a command."
user-invocable: false
---

<!-- generated by knowledge.mjs from 6 note(s) (sha256 d221acc07e84); edit the notes in knowledge/, then run build -->

# Test data factory rules (Python, factory_boy)

Apply these rules whenever you create or use a factory in a Python test.

## Always apply (critical, high)

### Set every value the test asserts on explicitly when you build test data

_high · any_

**Rule.** Build test data from a builder or factory, and pass an explicit override for every field the test
asserts on or branches on. Leave random values only in fields the test never looks at. Use named
variants (traits) for whole states such as "admin" or "inactive" instead of repeating the same
overrides in many tests.

**Why.** An assertion against a randomly generated value passes or fails depending on the seed, and a
reader cannot tell from the test which value matters. An explicit override documents the input the
test depends on and makes the failure reproducible.

### Pass asserted values as keyword arguments and model states as Traits

_high · python, factory-boy_

**Rule.** Pass every value the test asserts on as a keyword argument to the factory call. Use
`build_batch(size, **kwargs)` for lists. Define recurring states as `factory.Trait` in the
factory's `class Params` and switch them on with `admin=True`.

**Why.** A Faker-generated name asserted in a test passes only by coincidence of the seed, and the reader
cannot see which input the test depends on.

**Incorrect:**

```python
user = UserFactory.build()
assert render_greeting(user) == f"Hello, {user.name}"
```

**Correct:**

```python
class UserFactory(factory.Factory):
    class Meta:
        model = User

    name = factory.Faker("name")
    role = "member"

    class Params:
        admin = factory.Trait(role="admin")


user = UserFactory.build(name="Ada Lovelace")
admins = UserFactory.build_batch(3, admin=True)
assert render_greeting(user) == "Hello, Ada Lovelace"
```

**Exceptions.** Under `mypy --strict` the example above fails: `factory.Factory` takes no type argument through the `factory` package, and the declarations are untyped calls. Import `Factory` from `factory.base` and subclass `Factory[User]`, import `Faker` from `factory.faker` and `Trait` from `factory.declarations`, and silence the remaining `no-untyped-call` on each declaration with a reason: `# type: ignore[no-untyped-call]  # factory_boy declarations are untyped`.

## Read when the task touches it

| Impact | Rule | Applies to |
| --- | --- | --- |
| medium | [Reset builder counters and random state between tests that depend on them](references/rules.md#reset-builder-counters-and-random-state-between-tests-that-depend-on-them) — Sequences and seeded randomness carry over between tests; reset them where a test depends on their values. | any |
| medium | [Build structured test data with a builder, not inline object literals](references/rules.md#build-structured-test-data-with-a-builder-not-inline-object-literals) — Typed objects with three or more fields come from a shared builder; reuse an existing one before writing one. | any |
| medium | [Call Factory.build() unless the test needs the row in the database](references/rules.md#call-factorybuild-unless-the-test-needs-the-row-in-the-database) — Calling the factory directly runs create() and writes to the database; build() keeps a test in memory. | python, factory-boy |
| medium | [Reset factory sequences in setup when a test depends on sequence values](references/rules.md#reset-factory-sequences-in-setup-when-a-test-depends-on-sequence-values) — Factory.reset_sequence() restarts a Sequence; factory.random.reseed_random() makes Faker values reproducible. | python, factory-boy |

Files in this skill

  • SKILL.md4 KB
  • references/rules.md3.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in development →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.