View Source Sentry.Test.Assertions (Sentry v13.0.1)
ExUnit assertion helpers for testing Sentry reports.
These helpers work with data collected by Sentry.Test and reduce
boilerplate when asserting on captured events, transactions, and logs.
Usage
import Sentry.Test.AssertionsExamples
Assert that exactly one event was captured with specific fields:
assert_sentry_report(:event, level: :error, message: %{formatted: "hello"})Assert a transaction:
assert_sentry_report(:transaction, transaction: "my_span")Use the log shorthand:
assert_sentry_log(:info, "User session started")
assert_sentry_log(:info, ~r/session started/, trace_id: "abc123")Use the metric shorthand (find semantics — works with multiple co-emitted metrics):
assert_sentry_metric(:counter, name: "button.clicks")
assert_sentry_metric(:distribution, name: "response.time")Find a specific event among many:
events = Sentry.Test.pop_sentry_reports()
event = find_sentry_report!(events, message: %{formatted: ~r/hello/})Awaiting Asynchronous Reports
Log and metric events flow through the Sentry.TelemetryProcessor pipeline
asynchronously. The type-form of assert_sentry_report/2 and
assert_sentry_log/3 await internally — they flush the telemetry pipeline
and poll the collector with exponential backoff until at least one matching
item is captured, up to a timeout (default 1000ms).
Tests typically do not need to call Sentry.TelemetryProcessor.flush/0
or Process.sleep/1 before these assertions.
Override the default via the reserved :timeout keyword:
assert_sentry_report(:log, [level: :info, body: "hi"], timeout: 2000)
assert_sentry_log(:info, "hi", timeout: 2000)
assert_sentry_metric(:counter, name: "clicks", timeout: 2000)
Summary
Functions
Asserts that a log was captured matching the given level and body pattern.
Asserts that a metric was captured matching the given type and criteria.
Asserts that a report matches the given criteria.
Finds the first item in items that matches all criteria.
Functions
assert_sentry_log(level, body_pattern, extra_criteria \\ [])
View Source (since 13.0.0)@spec assert_sentry_log(Sentry.LogEvent.level(), String.t() | Regex.t(), keyword()) :: Sentry.LogEvent.t()
Asserts that a log was captured matching the given level and body pattern.
Awaits asynchronously-captured logs: the pipeline is flushed and the
collector is polled until a log matching the criteria is found or the
timeout elapses (default 1000ms, overridable via the :timeout
reserved key in extra_criteria).
Once at least one candidate log is available, finds the first one matching
level and body_pattern. This uses find semantics (not assert-exactly-1)
because logs often come in batches.
The optional third argument is a keyword list of extra criteria to match
on any Sentry.LogEvent field, plus the reserved :timeout option.
Returns the matched log event.
Examples
assert_sentry_log(:info, "User session started")
assert_sentry_log(:error, ~r/connection refused/)
assert_sentry_log(:info, "User session started", trace_id: "abc123")
assert_sentry_log(:info, "User session started", attributes: %{id: 312})
assert_sentry_log(:info, "slow path", timeout: 2000)
@spec assert_sentry_metric( :counter | :distribution | :gauge, keyword() ) :: Sentry.Metric.t()
Asserts that a metric was captured matching the given type and criteria.
Awaits asynchronously-captured metrics: the pipeline is flushed and the
collector is polled until a metric matching the criteria is found or the
timeout elapses (default 1000ms, overridable via the :timeout
reserved key in criteria).
Uses find semantics (not assert-exactly-1), so this succeeds even when multiple metrics were emitted together — as is common when a single request records several measurements.
Unmatched metrics are returned to an inbox so that multiple successive
assert_sentry_metric/2 calls in the same test each see a clean slate.
Returns the matched metric.
Examples
assert_sentry_metric(:counter, name: "button.clicks")
assert_sentry_metric(:distribution, name: "response.time", value: 42.5)
assert_sentry_metric(:gauge, name: "memory.usage", attributes: %{pool: "main"})
assert_sentry_metric(:counter, name: "requests", timeout: 2000)
@spec assert_sentry_report( :event | :transaction | :log | :metric, keyword() ) :: Sentry.Event.t() | Sentry.Transaction.t() | Sentry.LogEvent.t() | Sentry.Metric.t()
@spec assert_sentry_report(map() | [map()], keyword() | [{binary(), term()}]) :: map()
Asserts that a report matches the given criteria.
This function has two forms:
Auto-pop by type
When the first argument is a type atom (:event, :transaction, or :log),
it pops collected items internally — no need to call pop_sentry_reports/0
yourself. Asserts that exactly one item was captured and validates it.
:event— pops fromSentry.Test.pop_sentry_reports/0:transaction— pops fromSentry.Test.pop_sentry_transactions/0:log— pops fromSentry.Test.pop_sentry_logs/0
Explicit data
When the first argument is a map or single-element list, it validates the item against the criteria directly. Use this with data from envelope collection helpers.
Criteria
Each key-value pair in criteria is checked against the item:
- Regex — matches with
=~/2 - Plain map (not a struct) — recursive subset match: every key in the expected map must exist in the actual value with a matching value
- Any other value — compared with
==/2
Atom keys are resolved with a string-key fallback, so atom-key criteria also work on decoded JSON maps.
Returns the matched item for further assertions.
Examples
event = assert_sentry_report(:event,
level: :error,
source: :plug,
message: %{formatted: "hello"}
)
assert_sentry_report(:transaction, transaction: "test_span")
# With explicit data from envelope collection:
[event] = collect_sentry_events(ref, 1)
assert_sentry_report(event, "tags" => %{"oban_queue" => "default"})
Finds the first item in items that matches all criteria.
Raises with a descriptive error if no match is found. Works with both structs (atom keys) and decoded JSON maps (string keys).
Examples
events = Sentry.Test.pop_sentry_reports()
event = find_sentry_report!(events, message: %{formatted: ~r/hello/})