# Let ExUnit shut down your test processes

Start test-owned processes with `start_supervised!/1` so ExUnit waits for them to shut down before running your cleanup callbacks.

```elixir
test "stops the worker before cleanup" do
  pid = start_supervised!({Agent, fn -> %{} end})

  on_exit(fn ->
    refute Process.alive?(pid)
  end)

  assert Agent.get(pid, & &1) == %{}
end
```

ExUnit stops the test supervisor and its children before running `on_exit`. The assertion inside the callback demonstrates that ordering; you do not need to add it to every test.

Starting a worker directly with `start_link` gives you a link, but shutdown through that link is asynchronous. The test process can exit before the worker finishes stopping. Cleanup that removes files or releases resources the worker still uses can race with it.

Use the test supervisor to make that boundary explicit. It accepts a child specification or a `{Module, arguments}` tuple, and `start_supervised!` returns the child PID.

This guarantee covers children managed by the test supervisor. A process spawned independently elsewhere still needs its own lifecycle management.

[ExUnit.Callbacks.start_supervised/2](https://hexdocs.pm/ex_unit/ExUnit.Callbacks.html#start_supervised/2)


---

Created by: almirsarajcic
Date: September 12, 2026
URL: https://elixirdrops.net/d/LgBiUAfo
