PropertyDamage.ExUnit (PropertyDamage v0.2.0)
View SourceExUnit integration for PropertyDamage property tests.
This module provides macros for writing property-based tests that integrate seamlessly with ExUnit. Tests can be defined using module attributes for configuration, with individual test overrides as needed.
Usage
defmodule MySystemTest do
use ExUnit.Case
use PropertyDamage.ExUnit
property_damage "system maintains invariants",
model: MyApp.TestModel,
adapter: MyApp.TestAdapter,
max_commands: 50,
max_runs: 100
property_damage "handles concurrent access",
model: MyApp.TestModel,
adapter: MyApp.ConcurrentAdapter,
max_commands: 100
endTest Options
Options passed to property_damage/2:
Required:
:model- Model module (required):adapter- Adapter module (required)
Optional: every other PropertyDamage.run/1 option is forwarded as-is,
including:
:max_commands- Max commands per sequence (default: 50):max_runs- Number of test sequences (default: 100):seed- Fixed seed for reproducibility:injector_adapters- List of injector adapter modules (default: []):shrink- Whether to shrink failures (default: true):validate- Whether to validate config (default: true):adapter_config- Config passed to adapter.setup/1 (default: %{}):verbose,:assertion_mode,:branching,:stutter,:external_markers,:on_failure, and the rest of therun/1surface
Defaults are applied by run/1 itself; a nil :seed is dropped so the
run picks a random seed.
Failure Formatting
When a property test fails, the output includes:
- The seed for reproducing the failure
- The original command sequence
- The shrunk (minimal) command sequence
- The failure reason
- Instructions for reproducing with the same seed
Example Failure Output
1) property system maintains invariants
Failure with seed: 12345
Original sequence (5 commands):
[%CreateItem{...}, %ViewItem{...}, ...]
Shrunk sequence (2 commands):
[%CreateItem{quantity: 101}]
Failed at command #0:
{:check_failed, :quantity_limit, "Quantity 101 exceeds limit"}
Reproduce with: seed: 12345
Summary
Functions
Use this module to enable PropertyDamage test macros.
Assemble the options forwarded to PropertyDamage.run/1 for a
property_damage/2 test.
Format a failure report for ExUnit output.
Define a property-based test.
Functions
Use this module to enable PropertyDamage test macros.
Requires use ExUnit.Case to be called first.
Example
defmodule MyTest do
use ExUnit.Case
use PropertyDamage.ExUnit
@model MyModel
@adapter MyAdapter
property_damage "test name" do
max_runs: 10
end
end
Assemble the options forwarded to PropertyDamage.run/1 for a
property_damage/2 test.
:model and :adapter are required (a missing one raises KeyError with a
clear message); every other option is forwarded verbatim, so the full
run/1 surface (verbose:, assertion_mode:, branching:, stutter:,
external_markers:, on_failure:, ...) is reachable from the ExUnit macro.
run/1 validates the result and applies its own defaults for any omitted
option, so this function deliberately does not re-specify them. A nil
:seed is dropped so run/1 picks a random seed.
@spec format_failure(PropertyDamage.FailureReport.t()) :: String.t()
Format a failure report for ExUnit output.
Produces human-readable output with all relevant information for debugging and reproducing the failure.
Define a property-based test.
Creates an ExUnit test that generates and executes command sequences, checking for invariant violations.
Parameters
name- Test name (string)opts- Options keyword list (see module docs for available options)
Examples
# Basic usage
property_damage "basic test",
model: MyModel,
adapter: MyAdapter
# With options
property_damage "custom test",
model: MyModel,
adapter: MyAdapter,
max_commands: 100,
max_runs: 50
# With fixed seed for reproduction
property_damage "reproducible test",
model: MyModel,
adapter: MyAdapter,
seed: 12345