View Source Sentry.Test (Sentry v13.0.1)
Utilities for testing Sentry reports.
Usage
This module provides helpers that set up a local HTTP server (via Bypass) so that
Sentry SDK calls in your tests hit a local endpoint instead of the real Sentry API.
Events are captured via the existing before_send and before_send_log callbacks
and stored in an isolated ETS table per test, preserving the full struct data.
Bypass Required
This module requires
bypassas a test dependency:{:bypass, "~> 2.0", only: [:test]}
Examples
The simplest way to use this module is with the setup_sentry/1 function:
defmodule MyApp.ErrorReportingTest do
use ExUnit.Case, async: true
setup do
Sentry.Test.setup_sentry()
end
test "reports exceptions to Sentry" do
try do
raise "boom"
rescue
e -> Sentry.capture_exception(e)
end
assert [%Sentry.Event{} = event] = Sentry.Test.pop_sentry_reports()
assert event.original_exception == %RuntimeError{message: "boom"}
end
endYou can also use start_collecting_sentry_reports/0 as an ExUnit setup callback
for backwards compatibility:
setup :start_collecting_sentry_reportsAssertion Helpers
See Sentry.Test.Assertions for convenient assertion functions that reduce
boilerplate when validating captured events, transactions, and logs.
Summary
Functions
Allows pid_to_allow to collect events back to the root process via owner_pid.
Cleans up test resources associated with owner_pid.
Collects decoded envelopes sent to a Bypass collector.
Collects check-in payloads sent through a Bypass envelope collector.
Collects events sent through a Bypass envelope collector.
Collects log items sent through a Bypass envelope collector.
Collects metric batch payloads sent through a Bypass envelope collector.
Collects transactions sent through a Bypass envelope collector.
Decodes a raw envelope binary into a list of {header, item} tuples.
Extracts check-in payloads from decoded envelope item lists.
Extracts event payloads from decoded envelope item lists.
Extracts log item payloads from decoded envelope item lists.
Extracts metric batch payloads from decoded envelope item lists.
Extracts transaction payloads from decoded envelope item lists.
Pops all the collected log events from the current process.
Pops all the collected metrics from the current process.
Pops all the collected events from the current process.
Pops all the collected transactions from the current process.
Sets up a Bypass envelope collector that forwards envelope bodies to the test process as messages.
Sets up a Bypass instance and configures Sentry for testing.
Starts an isolated, per-test Sentry.TelemetryProcessor and wires it
into the current test's config scope.
Starts collecting events.
Starts collecting events from the current process.
Functions
Allows pid_to_allow to collect events back to the root process via owner_pid.
Deprecated
This function is deprecated and will be removed in v13.0.0. Child processes are automatically tracked via the
$callersmechanism. There is no need to explicitly allow processes.
@spec cleanup(pid()) :: :ok
Cleans up test resources associated with owner_pid.
Deprecated
This function is deprecated and will be removed in v13.0.0. Cleanup is now handled automatically via
on_exitcallbacks.
@spec collect_envelopes(reference(), pos_integer(), keyword()) :: [[{map(), map()}]]
Collects decoded envelopes sent to a Bypass collector.
Returns a list of decoded envelope item lists. Each element is the result
of decode_envelope!/1 for one HTTP request.
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
collect_sentry_check_ins(ref, expected_count, opts \\ [])
View Source (since 13.0.0)@spec collect_sentry_check_ins(reference(), pos_integer(), keyword()) :: [map()]
Collects check-in payloads sent through a Bypass envelope collector.
This is a high-level helper combining collect_envelopes/3 and extract_check_ins/1.
Use this instead of manually destructuring [[{header, body}]] from collect_envelopes/3.
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
Examples
ref = setup_bypass_envelope_collector(bypass, type: "check_in")
Sentry.capture_check_in(status: :ok, monitor_slug: "my-job")
[check_in] = collect_sentry_check_ins(ref, 1)
assert check_in["status"] == "ok"
collect_sentry_events(ref, expected_count, opts \\ [])
View Source (since 13.0.0)@spec collect_sentry_events(reference(), pos_integer(), keyword()) :: [map()]
Collects events sent through a Bypass envelope collector.
This is a high-level helper combining collect_envelopes/3 and extract_events/1.
Use this instead of collect_envelopes(ref, count) |> extract_events().
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
Examples
ref = setup_bypass_envelope_collector(bypass)
trigger_event()
[event] = collect_sentry_events(ref, 1)
collect_sentry_logs(ref, expected_count, opts \\ [])
View Source (since 13.0.0)@spec collect_sentry_logs(reference(), pos_integer(), keyword()) :: [map()]
Collects log items sent through a Bypass envelope collector.
This is a high-level helper combining collect_envelopes/3 and extract_log_items/1.
Use this instead of collect_envelopes(ref, count) |> extract_log_items().
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
Examples
ref = setup_bypass_envelope_collector(bypass)
Logger.info("something happened")
[log] = collect_sentry_logs(ref, 1)
collect_sentry_metric_items(ref, expected_count, opts \\ [])
View Source (since 13.0.0)@spec collect_sentry_metric_items(reference(), pos_integer(), keyword()) :: [map()]
Collects metric batch payloads sent through a Bypass envelope collector.
This is a high-level helper combining collect_envelopes/3 and extract_metric_items/1.
Use this instead of collect_envelopes(ref, count) |> extract_metric_items().
Each returned map has an "items" key containing the individual metric maps.
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
Examples
ref = setup_bypass_envelope_collector(bypass, type: "trace_metric")
Sentry.Metrics.count("button.clicks", 1)
[batch] = collect_sentry_metric_items(ref, 1)
[metric] = batch["items"]
assert metric["name"] == "button.clicks"
collect_sentry_transactions(ref, expected_count, opts \\ [])
View Source (since 13.0.0)@spec collect_sentry_transactions(reference(), pos_integer(), keyword()) :: [map()]
Collects transactions sent through a Bypass envelope collector.
This is a high-level helper combining collect_envelopes/3 and extract_transactions/1.
Use this instead of collect_envelopes(ref, count) |> extract_transactions().
Options
:timeout- timeout in ms to wait for each envelope (default: 1000)
Examples
ref = setup_bypass_envelope_collector(bypass)
run_traced_job()
[tx] = collect_sentry_transactions(ref, 1)
Decodes a raw envelope binary into a list of {header, item} tuples.
Extracts check-in payloads from decoded envelope item lists.
Extracts event payloads from decoded envelope item lists.
Extracts log item payloads from decoded envelope item lists.
Extracts metric batch payloads from decoded envelope item lists.
Each returned map has an "items" key containing the individual
metric maps for that batch. This mirrors the structure of extract_log_items/1.
Extracts transaction payloads from decoded envelope item lists.
@spec pop_sentry_logs(pid()) :: [Sentry.LogEvent.t()]
Pops all the collected log events from the current process.
Returns a list of all Sentry.LogEvent structs that have been collected.
After this function returns, the collected log events are cleared but
collection continues.
Logs are Asynchronous
Log events flow through the
TelemetryProcessorpipeline asynchronously. You may need to add a small delay before calling this function to ensure all log events have been processed by thebefore_send_logcallback.
@spec pop_sentry_metrics(pid()) :: [Sentry.Metric.t()]
Pops all the collected metrics from the current process.
Returns a list of all Sentry.Metric structs that have been collected.
After this function returns, the collected metrics are cleared but
collection continues.
Metrics are Asynchronous
Metric events flow through the
TelemetryProcessorpipeline asynchronously. You may need to add a small delay before calling this function to ensure all metrics have been processed by thebefore_send_metriccallback.
@spec pop_sentry_reports(pid()) :: [Sentry.Event.t()]
Pops all the collected events from the current process.
Returns a list of all Sentry.Event structs that have been collected from the
current process and all child processes spawned from it. After this function
returns, the collected events are cleared but collection continues.
Examples
iex> Sentry.Test.start_collecting_sentry_reports()
:ok
iex> Sentry.capture_message("Oops")
{:ok, ""}
iex> [%Sentry.Event{} = event] = Sentry.Test.pop_sentry_reports()
iex> event.message.formatted
"Oops"
@spec pop_sentry_transactions(pid()) :: [Sentry.Transaction.t()]
Pops all the collected transactions from the current process.
Returns a list of all Sentry.Transaction structs that have been collected.
After this function returns, the collected transactions are cleared but
collection continues.
Examples
iex> Sentry.Test.start_collecting_sentry_reports()
:ok
iex> Sentry.send_transaction(Sentry.Transaction.new(%{span_id: "123", start_timestamp: "2024-10-12T13:21:13", timestamp: "2024-10-12T13:21:13", spans: []}))
{:ok, ""}
iex> [%Sentry.Transaction{}] = Sentry.Test.pop_sentry_transactions()
setup_bypass_envelope_collector(bypass, opts \\ [])
View Source (since 13.0.0)Sets up a Bypass envelope collector that forwards envelope bodies to the test process as messages.
Uses Bypass.stub (not Bypass.expect) to be resilient to stray requests
from background processes (e.g., OpenTelemetry span processor).
Use with collect_envelopes/3 to retrieve the decoded envelopes.
Options
:type- when set, only envelopes containing an item of this type (e.g.,"event","transaction","log") are forwarded to the test process. Envelopes not matching the type are silently dropped.
Sets up a Bypass instance and configures Sentry for testing.
Opens a Bypass on a random port, configures the DSN to point to it,
wires up before_send / before_send_log callbacks to capture structs
in an isolated ETS table, and starts a per-test Sentry.TelemetryProcessor
(via setup_telemetry_processor/0) so that assertions work for events
that travel through the TelemetryProcessor pipeline (logs, metrics, or
send_result: :none).
Returns a map with :bypass and :telemetry_processor for use in test
context. The :telemetry_processor value is the atom name of the
per-test processor and can be used to stop_supervised!/1 and start
a custom-configured one when needed.
Options
Any extra Sentry config options (e.g., dedup_events: false, traces_sample_rate: 1.0)
will be forwarded to the test config.
Examples
setup do
Sentry.Test.setup_sentry()
end
setup do
Sentry.Test.setup_sentry(dedup_events: false)
endReplacing the auto-started processor with a custom-configured one:
setup do
%{telemetry_processor: name} = ctx = Sentry.Test.setup_sentry()
stop_supervised!(name)
start_supervised!(
{Sentry.TelemetryProcessor,
name: name, buffer_configs: %{log: %{batch_size: 1}}},
id: name
)
ctx
end
@spec setup_telemetry_processor() :: atom()
Starts an isolated, per-test Sentry.TelemetryProcessor and wires it
into the current test's config scope.
This is called automatically by setup_sentry/1 and
start_collecting_sentry_reports/0, so most users do not need to invoke
it directly. It is exposed for tests that want to perform the setup
without opening a Bypass.
The helper:
- starts a fresh
Sentry.TelemetryProcessorunder the ExUnit test supervisor with a unique name, - allows the scheduler PID in
Sentry.Test.Configso that per-test config overrides reach it, - stores the processor name in the process dictionary under
:sentry_telemetry_processorso thatSentry.TelemetryProcessor.add/1and friends route to it.
Returns the processor name (an atom).
Must be called from within an ExUnit test because it uses
ExUnit.Callbacks.start_supervised!/2 for automatic cleanup.
If a per-test processor is already registered for this test (for example
when using Sentry.Case), this function is idempotent and returns the
existing processor name instead of starting a new one.
@spec start_collecting(keyword()) :: :ok
Starts collecting events.
Deprecated
This function is deprecated and will be removed in v13.0.0. Use
setup_sentry/1orstart_collecting_sentry_reports/0instead.
The :owner, :cleanup, and :key options are no longer supported and are ignored.
@spec start_collecting_sentry_reports(map()) :: :ok
Starts collecting events from the current process.
This function configures Sentry for testing using the default Bypass instance (started at application boot). It can be used as an ExUnit setup callback:
setup :start_collecting_sentry_reportsThe context parameter is ignored — it exists so this function can be used
as an ExUnit setup callback.