Packages
Process Intelligence and Conformance Checking for ExUnit (pm4pytest for Elixir)
Current section
Files
Jump to
Current section
Files
README.md
# pm4exunit
Process-conformance and latency assertions for ExUnit. Record the events your code emits during a
test, then assert that the trace follows an allowed process model and meets its time limits.
```elixir
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
```
## Install
```elixir
def deps do
[{:pm4exunit, "~> 26.11", only: :test}]
end
```
Requires Elixir 1.15 or later. No runtime dependencies.
## What it does
- **Conformance:** `assert_conformance/3` and `refute_conformance/3` replay a trace against one or
more valid paths using token-based replay, and report a fitness score in `0.0..1.0`. The
assertion passes only when fitness is at least `min_fitness` (default `1.0`) and no tokens are
missing.
- **Latency:** `assert_sla/4` bounds the time between two activities. Pass `max_seconds:` (or
`max_duration:`).
- **Recording:** each test gets its own session process (`%{pm4_session: pid}`) that stores events
and OCEL-style objects. Assertions also accept a `%Pm4ExUnit.TraceCollector{}` or a plain list
of events.
- **Reporting:** `Pm4ExUnit.Reporter` formats a result as TAP v13 or JUnit XML.
Replay semantics port the pm4vitest TBR engine, so the same model and trace score identically in
both. This is verified by `test/pm4exunit_cross_engine_vector_test.exs`.
## Documentation
The docs follow [Diátaxis](https://diataxis.fr). Start at [`docs/README.md`](docs/README.md).
| You want to | Read |
|---|---|
| Learn by doing | [Tutorials](docs/tutorials/first-conformance-test.md) |
| Solve a specific task | [How-to guides](docs/how-to/) |
| Look up an API | [Reference](docs/reference/api.md) |
| Understand the model | [Explanation](docs/explanation/token-based-replay.md) |
## Known limitations
- `assert_sla/4` uses the first occurrence of each activity. Repeated activities are not paired.
- An event with a missing timestamp gets `DateTime.utc_now()` when recorded
(`Pm4ExUnit.TraceCollector`). `Pm4ExUnit.Temporal` also falls back to `utc_now()` for any
timestamp that is not a `%DateTime{}` (or an ISO8601 `"time:timestamp"` string). Always pass
explicit `DateTime` timestamps when asserting SLAs.
- Object-centric querying (OCPQ) is not implemented. Objects are recorded but not queryable.
The `docs/` directory ships with the hex package and is rendered on HexDocs.
## License
MIT. See [LICENSE](LICENSE).