Canonical API, configuration, and contract reference.
- Definition:
FixtureKit.define { ... }returns aFixtureKit::Definition. - Fixture: wraps an identifier and a definition; handles cache save/mount.
- Cache: persists and replays SQL for touched models.
- Repository: exposes records via methods, loaded lazily and memoized per test.
- Runner: owns configuration, registry, startup state, and adapter instance.
Require:
require "fixture_kit/rspec"Effects:
- Configures
fixture_pathdefault to"spec/fixture_kit". - Configures adapter to
FixtureKit::RSpecAdapter. - Adds
fixtureclass macro for example groups. - Adds
fixtureinstance reader for examples.
Require:
require "fixture_kit/minitest"Effects:
- Configures
fixture_pathdefault to"test/fixture_kit". - Configures adapter to
FixtureKit::MinitestAdapter. - Adds
fixtureclass macro for test classes. - Adds
fixtureinstance reader for tests.
Declaration signature in both frameworks:
fixture(name = nil, &definition_block)Rules:
- Provide exactly one of
nameor block. - Both provided: raises
FixtureKit::InvalidFixtureDeclaration. - Neither provided: raises
FixtureKit::InvalidFixtureDeclaration. - More than one declaration in same context/class: raises
FixtureKit::MultipleFixtures. - Nested context/class can declare its own fixture and override parent declaration.
Named fixture lookup:
- Reads
<fixture_path>/<name>.rb. - File must evaluate to
FixtureKit::Definition. - Missing file or invalid return value raises
FixtureKit::FixtureDefinitionNotFound.
Anonymous fixture:
- Declared inline via block.
- Identifier is derived from framework scope class and normalized by adapter.
FixtureKit.define do
# setup data
expose(user: user)
endDefinition#expose(**records):
- Exposed names become repository methods.
- Duplicate exposed names raise
FixtureKit::DuplicateNameError.
Configure via:
FixtureKit.configure do |config|
# ...
endDefault values:
fixture_path:"fixture_kit"cache_path:"tmp/cache/fixture_kit"- adapter class:
FixtureKit::MinitestAdapter - adapter options:
{}
config.fixture_path = String
- Base directory for named fixture files.
config.cache_path = String
- Base directory for cache JSON files.
config.adapter(adapter_class = nil, **options)
- Getter: no args returns current adapter class.
- Setter: stores adapter class and options for adapter initialization.
config.callbacks
- Returns callback registry (
FixtureKit::Callbacks).
Subclass FixtureKit::Adapter and implement:
#execute { ... }
- Runs fixture generation in framework-specific isolation.
#identifier_for(identifier)
- Receives non-string fixture identifier and returns normalized String identifier.
_anonymous/prefixing is applied byFixtureKit::Cache.
Adapter initialization:
adapter_instance = config.adapter.new(config.adapter_options)Options are available via attr_reader :options in FixtureKit::Adapter.
Register using configuration methods:
config.on_cache_save { |identifier| ... }
- Runs before cache save.
config.on_cache_saved { |identifier, duration| ... }
- Runs after cache save.
durationis elapsed seconds asFloat.
config.on_cache_mount { |identifier| ... }
- Runs before cache mount.
config.on_cache_mounted { |identifier, duration| ... }
- Runs after cache mount.
durationis elapsed seconds asFloat.
Behavior:
- Multiple callbacks per event supported.
- Callbacks run in registration order.
identifieris always a String cache identifier (no.jsonsuffix).
Cache file path format:
<cache_path>/<identifier>.json
Identifier behavior:
- Named fixture: identifier is the fixture name string.
- Anonymous fixture: identifier is
_anonymous/<adapter-normalized-scope>.
Examples:
- Named:
teams/basic->tmp/cache/fixture_kit/teams/basic.json - Anonymous RSpec:
_anonymous/foo/with_fixture_kit/hello - Anonymous Minitest:
_anonymous/my_feature_test
fixture
- Returns
FixtureKit::Repositoryfor the mounted fixture.
Repository
- Methods are generated from exposed names.
- First access loads model with
find_by(id: ...). - Loaded value is memoized for subsequent access in that test.
- If row is missing before first access, value is
nil.
FIXTURE_KIT_PRESERVE_CACHE
- If truthy, runner start does not clear cache directory.
- Truthy values (case-insensitive):
1,true,yes.
Public error classes:
FixtureKit::ErrorFixtureKit::DuplicateNameErrorFixtureKit::InvalidFixtureDeclarationFixtureKit::MultipleFixturesFixtureKit::CacheMissingErrorFixtureKit::FixtureDefinitionNotFoundFixtureKit::RunnerAlreadyStartedError
- Ruby >= 3.3
- ActiveRecord >= 8.0
- ActiveSupport >= 8.0