fuelen

fuelen

SeedFactory - a toolkit for test data generation

GitHub | docs | Hex.pm

The main idea of SeedFactory is to generate test data by calling your application’s business logic (context functions if you use Phoenix Contexts) instead of inserting directly into the database. This means your tests work with data that was created the same way it would be in production. SeedFactory resolves dependencies automatically, so you don’t need to worry about the details of preparing data that your test doesn’t directly care about.

Even in cases where calling business logic functions is impractical (e.g. for performance reasons), SeedFactory serves as a centralized hub for test data creation, ensuring a consistent approach across your test suite.

The library is completely agnostic to the database toolkit.

See the Overview section on GitHub and docs for details.

Feel free to ask any questions!

Showing Posts 1 to 9

LostKobrakai

LostKobrakai

This is great. I’ve tried a bunch of factory approaches, but this one feels quite well executed and seems to cover the needs I generally have quite well. I also really like that it makes it impossible to insert data in a way the codebase wouldn’t.

hauleth

hauleth

That seems like super reasonable approach to factories. I already like that, however it feels a little bit macro heavy.

fuelen

fuelen OP

Actually, command resolver can use whatever code you need. So, you can use something that differs from the actual implementation, like a simplified version of it. But the fact that it is placed in a single centralized place makes it very maintainable.

When I read your comment for the first time, I was surprised why do you think so, as there is only 1 macro – produce/1. Completely forgot that DSL for schema definition is built on macros :smile: That’s because the heavy lifting is done by spark (@zachdaniel thank you for the library, support and quick bug fixing!)

I tried to describe the schema using simple structures in my initial implementation. But eventually, current implementation won.

fuelen

fuelen OP

SeedFactory v0.6.0 has been released :tada:

fuelen

fuelen OP

SeedFactory v0.7.0 Released :tada:

A big release with many internal changes

Same trait from multiple commands

The same trait can now be defined with different commands. This enables schemas that mirror real business logic where the same state can be reached through different paths:

command :create_user do
  # ... creates user with status: :pending
  produce :user
end

command :activate_user do
  param :user, entity: :user, with_traits: [:pending]
  # ... updates user to status: :active
  update :user
end

command :create_active_user do
  # ... creates user with status: :active directly
  produce :user
end

# :active can be reached via transition...
trait :active, :user do
  from :pending
  exec :activate_user
end

# ...or directly
trait :active, :user do
  exec :create_active_user
end

# Unique marker for the direct path
trait :pending_skipped, :user do
  exec :create_active_user
end

Usage:

# SeedFactory picks the first declared command by default
produce(ctx, user: [:active])

# Force a specific path using a trait unique to that command
produce(ctx, user: [:active, :pending_skipped])

When multiple commands can produce the same trait, SeedFactory automatically picks one based on which commands can satisfy their dependencies without duplicating existing entities.

Compile-time validations

Schemas are now validated more thoroughly at compile time with helpful “did you mean?” suggestions in error messages.

Documentation

README now includes an “Advanced features” section covering pre_exec/pre_produce, args_match/generate_args, and trail tracking.

fuelen

fuelen OP

SeedFactory v0.8.0 Released!

This release is focused on developer experience: better error reporting, improved documentation, and fewer dependencies.

Structured error reporting

When a command fails, you now get SeedFactory.ExecError with a visual execution plan showing what succeeded, what failed, and what was still pending:

** (SeedFactory.ExecError) unable to execute :create_user command: :email_already_taken

Execution plan:
  ✔ :create_company
  ✔ :create_office
  ✖ :create_user
  · :activate_user
  · :create_profile

Current traits:
  %{company: [], office: [:main]}

Execution history

Every produce/exec call is now recorded in meta, providing a full audit trail of how a context was built. Combined with a compact inspect format, it’s easy to see what happened:

#execution[produce(user: [:admin, :active]): create_company → create_user → activate_user]
#execution[produce(order: [:pending]): create_order]

Performance

Replaced libgraph dependency with an inline topological sort, optimized compile-time trait indexing, and fixed quadratic list accumulation — fewer dependencies and faster compilation.

fuelen

fuelen OP

SeedFactory v0.9.0 Released!

This release has a new dependency planner. It searches for a complete plan and backtracks when a choice doesn’t work out, including deciding the order in which commands run.

I also added test generators that exercise thousands of schemas and command sequences, plus tests that compare the planner’s results with all possible execution orders on small schemas. This helped cover a lot more combinations and fix quite a few bugs along the way.

dimitarvp

dimitarvp

Never got to tell you: I love the declarative approach of that library and would love to try it when I get the time. Every time I checked it (as you announce versions), I liked it.

fuelen

fuelen OP

Thanks, glad you like it! I like this approach too :grin:

I’m currently migrating some old tests from ex_machina to seed_factory before refactoring, and Claude reports that the tests end up with 20–25% fewer lines of code on average. But, of course, new tests aren’t byte-to-byte identical to the old ones, they’re improved a bit

— All posts loaded —

Where Next? Top

Trending in Announcing Top

mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New
quatermain
Hello, I’m sharing my plugin here in forum after some time so it has time to mature and proof yourself. I use Claude Code daily on a pr...
New
gtcode
Aloha gang, There’s a new class of AI model out from TypeSafe. Jev is their flagship model. You can learn about it here: ...
New
LostKobrakai
I’ve recently created a small library phoenix_vite integrating the vite build tooling with phoenix. It provides an igniter.installer t...
New
danschultzer
I needed something like premailer for rails, and after searching, I decided to make an easy-to-use library to handle inline styles and co...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New
CodeSync
Code BEAM Europe 2026 – Call for Talks is Open! We’re excited to announce that Code BEAM Europe 2026 is now open for talk submissions :t...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews