Ii finally end up with this:
defmodule MyApp.MetricsCase do
@moduledoc """
This module defines the setup for tests requiring metrics tests.
"""
use ExUnit.CaseTemplate
using do
quote do
import Sharon.MetricsCase
end
end
@doc """
Add a tag for metrics testing.
Takes a list of metrics as paramater.
## Usage
@tag metrics: [[:my_app, :metrics1], [:my_app, :metrics2, :sub]]
"""
setup tags do
if metrics = tags[:metrics] do
self = self()
:telemetry.attach_many(
tags[:test],
metrics,
fn name, measurements, metadata, _ ->
send(self, {:telemetry_event, name, measurements, metadata})
end,
nil
)
end
:ok
end
@doc """
Assert that given event has been sent.
"""
defmacro assert_metrics(name, measurements, metadata \\ %{}),
do: do_assert_metrics(name, measurements, metadata)
defp do_assert_metrics(name, measurements, %{}) do
do_assert_metrics(name, measurements, Macro.escape(%{}))
end
defp do_assert_metrics(name, measurements, metadata) do
quote do
assert_receive {:telemetry_event, unquote(name), unquote(measurements), unquote(metadata)}
end
end
end
which can be use
d in both test support file and test file.
My example test is now:
@tag metrics: [[:user, :create], [:user, :registration]]
test "user creation ok" do
Repo.insert!(user_data)
assert_metrics([:user, :create], %{count: 1})
assert_metrics([:user, :registration], %{count: 1}, %{stage: :creation})
end