Write your first conformance test

Copy Markdown

In this tutorial you will add pm4exunit to a project, record events in a test, and watch a conformance assertion pass and then fail. It takes about ten minutes.

1. Add the dependency

In mix.exs:

{:pm4exunit, "~> 26.11", only: :test}

Run mix deps.get.

2. Write a passing test

Create test/order_saga_test.exs:

defmodule OrderSagaTest do
  use ExUnit.Case
  use Pm4ExUnit

  test "order saga follows the model", %{pm4_session: session} do
    emit_event(session, "e1", :order_created)
    emit_event(session, "e2", :payment_processed)
    emit_event(session, "e3", :order_fulfilled)

    assert_conformance(session, [[:order_created, :payment_processed, :order_fulfilled]])
  end
end

use Pm4ExUnit starts a session for each test and passes it in the test context as :pm4_session. The list of lists is the model: each inner list is one allowed path.

Run mix test. The test passes.

3. Break it

Delete the :payment_processed line and run mix test again. The assertion fails with a message like:

Process Conformance Assertion Failed!
Minimum Fitness Required: 1.0
Observed Fitness: 0.5833
Violations:
  * Conformance fitness 0.5833 is below required minimum 1.0.
  * Trace missed 1 mandatory transition(s) in path: ["order_created", "payment_processed", "order_fulfilled"].
  * Trace ended with 1 unconsumed token(s) (premature termination or superfluous transitions).
Diagnostics:
  Trace: ["order_created", "order_fulfilled"]
  Missing Tokens: 1
  Remaining Tokens: 1

The expected path is printed in the violations; compare it with the trace under Diagnostics to see which step is missing.

4. Add a latency limit

Add a second test:

test "fulfilment is fast enough", %{pm4_session: session} do
  t0 = ~U[2026-11-12 10:00:00Z]

  emit_event(session, "e1", :order_created, timestamp: t0)
  emit_event(session, "e2", :order_fulfilled, timestamp: DateTime.add(t0, 2, :second))

  assert_sla(session, :order_created, :order_fulfilled, max_seconds: 5.0)
end

Change 2 to 9 and it fails with SLA violated.

Next