`:erlang.trace/3` allows a process to trace _all_ other process message send/receives by passing `:processes` as the first argument. Depending on how much overhead that adds, this could be called when any test process that includes a `assert_pid_receive` is started. I'm not familiar with ExUnit's internals, but the implementation could look something like
defmacro assert_pid_receive(pid, message, timeout \\ 5000) do
quote do
Module.put_attribute(__MODULE__, :needs_trace, __EX_UNIT_TEST_NAME__)
receive do
{:trace, unquote(pid), :receive, unquote(message)} ->
:ok
after
unquote(timeout) ->
{:error, :timeout}
end
# somewhere in test process bootstrap
if (__EX_UNIT_TEST_NAME__ in @needs_trace) do
:erlang.trace(:processes, true, [:receive])
end
```