Supertester is an OTP-focused testing toolkit for Elixir. It helps you write deterministic tests for concurrent systems without Process.sleep/1, while keeping tests async-safe through per-test isolation.
Version: 0.6.0
Installation
def deps do
[
{:supertester, "~> 0.6.0", only: :test}
]
endmix deps.get
Quick Example
defmodule MyApp.CounterTest do
use Supertester.ExUnitFoundation, isolation: :full_isolation
import Supertester.{OTPHelpers, GenServerHelpers, Assertions}
test "increments deterministically" do
{:ok, counter} = setup_isolated_genserver(Counter)
:ok = cast_and_sync(counter, :increment)
assert_genserver_state(counter, fn state -> state.count == 1 end)
end
endCore Modules
Supertester.ExUnitFoundation- ExUnit adapter with isolation wiring.Supertester.UnifiedTestFoundation- isolation runtime for custom harnesses.Supertester.TestableGenServer- injects:__supertester_sync__handlers.Supertester.OTPHelpers- isolated startup/teardown helpers.Supertester.GenServerHelpers- call/cast sync helpers and GenServer stress tools.Supertester.SupervisorHelpers- restart strategy and tree assertions.Supertester.ChaosHelpers- crash injection, supervisor chaos, suite runner.Supertester.PerformanceHelpers- time/memory/reduction assertions.Supertester.Assertions- OTP-aware process/supervisor assertions.Supertester.ConcurrentHarness- declarative multi-thread scenario runner.Supertester.PropertyHelpers- StreamData generators for scenarios.Supertester.MessageHarness- mailbox tracing for diagnostics.Supertester.Env- environment abstraction for custom test runner integration.Supertester.Telemetry,TelemetryHelpers,LoggerIsolation,ETSIsolation.
Behavioral Notes
cast_and_sync/4- When the sync handler replies
:ok(the defaultTestableGenServerbehavior), returns bare:ok. - When the sync handler replies with any other value (including error tuples), returns
{:ok, reply}. strict?: trueraisesArgumentErrorwhen synchronization support is missing.- Non-strict mode returns
{:error, :missing_sync_handler}when missing.
- When the sync handler replies
test_restart_strategy/3- validates expected supervisor strategy and raises on mismatch.
- raises
ArgumentErrorwhen scenario child IDs are unknown. - temporary removed children are not reported as restarted.
chaos_kill_children/2- accepts pid or registered supervisor name (atom,
{:global, _},{:via, _, _}). restartedcounts observed child replacements, including cascade replacements.
- accepts pid or registered supervisor name (atom,
run_chaos_suite/3- applies a suite-level timeout.
- only true per-scenario deadline overruns are treated as timeout cutoffs.
- scenarios that independently return
{:error, :timeout}do not stop the suite.
assert_no_process_leaks/1- tracks spawned/linked processes attributable to the operation.
- catches delayed descendant leaks.
- avoids flagging short-lived transient processes as leaks.
Safety
- No unbounded dynamic atom creation is used for test IDs or isolation naming paths.
- ETS fallback injection (
ETSIsolation.inject_table/3-4) uses existing atoms only and raises instead of creating dynamic atoms.
Documentation
Examples
License
MIT