README.md

# Supertester

<p align="center">
  <img src="assets/supertester-logo.svg" alt="Supertester Logo" width="200">
</p>

<p align="center">
  <a href="https://hex.pm/packages/supertester"><img alt="Hex.pm" src="https://img.shields.io/hexpm/v/supertester.svg"></a>
  <a href="https://hexdocs.pm/supertester"><img alt="Documentation" src="https://img.shields.io/badge/docs-hexdocs-purple.svg"></a>
  <a href="https://github.com/nshkrdotcom/supertester/actions"><img alt="Build Status" src="https://img.shields.io/github/actions/workflow/status/nshkrdotcom/supertester/ci.yml"></a>
  <a href="https://opensource.org/licenses/MIT"><img alt="License" src="https://img.shields.io/hexpm/l/supertester.svg"></a>
</p>

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

```elixir
def deps do
  [
    {:supertester, "~> 0.6.0", only: :test}
  ]
end
```

```bash
mix deps.get
```

## Quick Example

```elixir
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
end
```

## Core 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 default `TestableGenServer` behavior), returns bare `:ok`.
  - When the sync handler replies with any other value (including error tuples), returns `{:ok, reply}`.
  - `strict?: true` raises `ArgumentError` when synchronization support is missing.
  - Non-strict mode returns `{:error, :missing_sync_handler}` when missing.
- `test_restart_strategy/3`
  - validates expected supervisor strategy and raises on mismatch.
  - raises `ArgumentError` when 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, _, _}`).
  - `restarted` counts observed child replacements, including cascade replacements.
- `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

- [Documentation Index](guides/DOCS_INDEX.md)
- [Quick Start](guides/QUICK_START.md)
- [User Manual](guides/MANUAL.md)
- [API Guide](guides/API_GUIDE.md)
- [Changelog](CHANGELOG.md)

## Examples

- [Examples Index](examples/README.md)
- [EchoLab Example App](examples/echo_lab/README.md)

## License

MIT