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.Assertions

Examples

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

Link to this function

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)
Link to this function

assert_sentry_metric(type, criteria \\ [])

View Source (since 13.0.0)
@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)
Link to this function

assert_sentry_report(type_or_item, criteria)

View Source (since 13.0.0)
@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.

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"})
Link to this function

find_sentry_report!(items, criteria)

View Source (since 13.0.0)
@spec find_sentry_report!([map()], keyword() | [{binary(), term()}]) :: map()

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/})