Getting Started

Introduction

Why terse, readable tests matter for coding agents, and how Biome reduces setup and context overhead.

Why use Biome?

Tests are an important part of working with coding agents: they make expected behavior concrete and give an agent a way to check its changes. A clear test also helps the next reader or agent understand what needs to stay true. But that signal can get buried in the setup with long, repetitive boilerplate that increases token in and out. The problem is exacerbated when different human teammates using different agents produce different test setups and helper functions strewn across your codebase!

To illustrate, imagine a multi-tenant school management system, where each district has its own schools, classes, teachers, and students. A test that checks whether a class is full may first need to create a district, a school, a class, a teacher, and several students, all linked to the correct tenant.

Even one district and two schools require repeated setup (these examples keep the fields simple to the basics):

var now = DateTimeOffset.UtcNow;

// Required fields and an ID: needed for a valid row, but not what the test is about.
var district = new District
{
    Id = $"dist_{Guid.CreateVersion7():N}",
    Name = "Riverside Unified",
    TimeZoneId = "America/Chicago",
    CreatedAtUtc = now,
    UpdatedAtUtc = now,
};

// Every school repeats the tenant link and timestamps.
// This wiring uses up context without explaining the behavior under test.
var northHigh = new School
{
    Id = $"sch_{Guid.CreateVersion7():N}",
    DistrictId = district.Id,
    Name = "North High",
    Code = "NH",
    CreatedAtUtc = now,
    UpdatedAtUtc = now,
};

// Same wiring again; only the name and code differ.
var southHigh = new School
{
    Id = $"sch_{Guid.CreateVersion7():N}",
    DistrictId = district.Id,
    Name = "South High",
    Code = "SH",
    CreatedAtUtc = now,
    UpdatedAtUtc = now,
};

Add classes, teachers, and students, and the IDs, required fields, relationships, and timestamps can take dozens of lines before the assertion. Repeating that setup creates long tests and makes the behavior under test harder to spot. It also fills an agent's context with routine values and wiring that do not explain why the test exists.

Zeeq Biome moves those routine choices into reusable blueprints, so each test describes the scenario and the values that matter. The result is terse, readable tests that need less context to author and understand, for people and coding agents alike. A biome is your app's entity graph in miniature: just the rows one test needs, wired together correctly. The library targets .NET 10; the extension-block examples use C# 14.

  • You declare a blueprint for each entity type, with valid defaults that most tests can leave alone.
  • A test uses a short fluent chain to describe its scenario and set the properties it depends on.
  • Parents and children are typed, numbers and ordering come from sequences, the clock is controlled, and persistence is pluggable (EF Core or none).
When setup repeats every default, the reader has to guess which values matter. Customize only the property under test so the setup points to the behavior you want to check.

The payoff

A district report test needs one district with two schools. Here is the same setup as above, with and without Biome (toggle the tab and expand the non-Biome example):

await TestBiome.Start(_db, out _)
    .AddDistrict(out var district)
    .AddSchools(out var schools, 2)
    .BuildAsync();
_db.ChangeTracker.Clear();
Both versions build the same graph shape: one district with two schools. With Biome, the IDs, tenant links, and timestamps live once in the blueprints, so the test reads as the scenario. That is less for an agent to write, read, and check against its own changes.

The savings compound as the test suite grows. Defaults and relationship wiring are defined once, and every new test reuses them. Each test skips repeated setup, gives reviewers less to read, and spends less agent context on routine values. As people and agents accumulate more tests, those small savings become a substantial reduction in code and context across the suite.

TestBiome, AddDistrict, and AddSchools are helpers you define for your app. Their blueprints supply the defaults and relationships shown above.

Why "biome"

The name reflects the idea of a small, self-consistent environment. A useful test fixture contains the entities that interact in this scenario, with valid relationships between them. That idea carries through the vocabulary:

TermMeaning
SeedThe baseline every test starts from: an owner, an organization, whatever your app always needs.
BlueprintThe recipe for one entity type: a factory plus optional traits and derived defaults.
SequenceA declared-once counter or rank, scoped per session, parent or ancestor.
AnchorThe typed parent the next Add attaches to. Every Add re-anchors to its own output.
StoreWhere the finished biome is saved: EF Core, none, or your own IBiomeStore.

Biome's key heuristic:

Defaults make setup shorter, but they should not undo the value a test chose. Biome runs customizers before derived and global defaults, which fill only unset properties. The test's chosen value takes precedence over those defaults. See Customizing for the order and what counts as unset.

Packages

PackageContentsDependencies
Zeeq.BiomeCore: session, builder, blueprints, sequences, time, hooks, IBiomeStore, NullStorenone
Zeeq.Biome.EntityFrameworkCoreEfCoreStore and db.AsBiomeStore()Microsoft.EntityFrameworkCore 10+

Where is Biome used?

Biome's underlying approach was first introduced in Motion's backend codebase when the team made the transition to C#. A few months into the move, agentic coding took off and with it, the generation of hundreds of thousands of lines of test code! The original idea was to reduce the replication of the scaffolding for the tests while also improving the legibility of the test for quick scanning in code reviews. The side effect is that it also improved token usage in and out!

When Zeeq was spun out of Motion, this same approach was carried forward for the testing setup.

Biome is a generalization of this pattern into a reusable library so other teams can leverage this pattern to reduce boilerplate and improve the clarity of their tests.

Where next

  1. Install the package.
  2. Follow the Quick start to write your first blueprint and test.
  3. Read the guides, or browse the examples.