PostHog.Test (posthog v2.1.0)
View SourcePostHog Test Utilities Module
PostHog makes it simple to test captured events. Make sure to set test_mode in your config/test.exs:
config :posthog,
test_mode: trueNow PostHog will not send your captured events to the server and will instead keep them in memory, easily accessible for assertions:
test "capture event" do
PostHog.capture("event", %{distinct_id: "distinct_id"})
assert [event] = PostHog.Test.all_captured()
assert %{
event: "event",
distinct_id: "distinct_id",
properties: %{},
timestamp: _
} = event
endConcurrency
PostHog uses NimbleOwnership ownership mechanism to determine
which events belong to which tests. This should work very well for most tests.
However, in some cases captured events cannot be traced back to tests. Those
tests are usually well-known and are run with async: false mode. For those,
PostHog lets you enable "global" or "shared" mode, where all events captured
within the system will be accessible by the test.
To switch PostHog to shared mode, just call PostHog.Test.set_posthog_shared/1
in your setup:
defmodule MyTest do
use ExUnit.Case, async: false
setup_all {PostHog.Test, :set_posthog_shared}
test "complex test" do
# run some code
assert events = PostHog.Test.all_captured()
assert Enum.any?(events, & match?(%{event: "my event"}, &1))
end
endPostHog will revert back from shared mode to private once the test suite or test process exits.
Assertions in shared mode
In shared mode, your test can easily pick up events from background jobs, other tests, or some rogue processes. Design your assertions accordingly to avoid flaky tests!
Summary
Functions
Retrieves all events captured by PostHog.
Allows a process to share captured events with another process.
Sets PostHog to shared (or "global") mode.
Functions
@spec all_captured(PostHog.supervisor_name()) :: [map()]
Retrieves all events captured by PostHog.
In private mode, these are all events that can be attributed to the current process via ownership.
In shared mode, these are all captured events.
@spec allow(PostHog.supervisor_name(), pid(), pid() | (-> resolved_pid)) :: :ok | {:error, NimbleOwnership.Error.t()} when resolved_pid: pid() | [pid()]
Allows a process to share captured events with another process.
Imagine that your test spawns an asynchronous process that captures an event. By default, the test process won't be able to access this event. To mitigate this, the test process should explicitly allow the spawned process' events to appear in its own personal stash of captured events.
test "allowance" do
test_pid = self()
pid =
spawn(fn ->
receive do
:go -> :ok
end
PostHog.capture("event", "user123")
send(test_pid, :ready)
end)
PostHog.Test.allow(test_pid, pid)
send(pid, :go)
assert_receive :ready
assert [%{event: "event"}] = PostHog.Test.all_captured()
endCaller Tracking
In practice, explicit allowances are a tool of last resort. Caller tracking allows for automatic ownership propagation. Designing your app with this in mind is the key to painless testing.