PropertyDamage.Mutation (PropertyDamage v0.2.0)
View SourceMutation testing for PropertyDamage.
Mutation testing verifies that your property-based tests are effective by:
- Injecting faults (mutations) into adapter responses
- Running tests against the mutated responses
- Checking if tests catch (kill) the mutations
A killed mutant means your tests detected the simulated bug (good). A survived mutant means your tests missed the bug (bad - weak tests).
Usage
# Run mutation testing
{:ok, report} = PropertyDamage.Mutation.run(
model: MyModel,
adapter: MyAdapter,
adapter_config: %{base_url: "http://localhost:4000"},
target_score: 0.80
)
# Check if tests are effective
if PropertyDamage.Mutation.passes?(report) do
IO.puts("Tests are effective!")
else
IO.puts("Tests need improvement")
IO.puts(PropertyDamage.Mutation.format(report))
end
# Get detailed analysis
analysis = PropertyDamage.Mutation.analyze(report)
IO.puts(PropertyDamage.Mutation.Analysis.format(analysis))Mutation Operators
:value- Mutates numeric and string values (zero, negate, off-by-one):omission- Removes fields from events:status- Changes success/error outcomes:event- Modifies event contents and structure:boundary- Pushes values to edge cases (0, -1, max, nil)
Options
:model- The model module (required):adapter- The adapter module (required):adapter_config- Configuration for the adapter:operators- List of operator names (default: all):mutations_per_command- Max mutations per command (default: 5):max_runs- Property test runs per mutation (default: 10):target_score- Target mutation score (default: 0.80):timeout_ms- Timeout per mutation test (default: 30000):verbose- Print progress (default: false)
Summary
Functions
Analyzes a mutation report to identify weaknesses.
Returns all available mutation operator names.
Formats a mutation report for display.
Checks if a mutation report passes the target score.
Runs mutation testing against a model.
Returns the weakest commands from a report, sorted by kill rate.
Returns the weakest operators from a report, sorted by kill rate.
Functions
@spec analyze(PropertyDamage.Mutation.Report.t()) :: PropertyDamage.Mutation.Analysis.analysis()
Analyzes a mutation report to identify weaknesses.
Returns insights about:
- Weak commands (low kill rates)
- Weak operators (types of mutations that survive)
- Unchecked fields
- Actionable suggestions
Examples
analysis = PropertyDamage.Mutation.analyze(report)
IO.puts(analysis.summary)
Enum.each(analysis.suggestions, &IO.puts/1)
@spec available_operators() :: [atom()]
Returns all available mutation operator names.
Examples
PropertyDamage.Mutation.available_operators()
# => [:value, :omission, :status, :event, :boundary]
@spec format(PropertyDamage.Mutation.Report.t(), atom()) :: String.t()
Formats a mutation report for display.
Formats
:terminal- ASCII boxes for console output (default):markdown- Markdown tables for documentation:json- JSON for programmatic analysis
Examples
IO.puts(PropertyDamage.Mutation.format(report))
IO.puts(PropertyDamage.Mutation.format(report, :markdown))
@spec passes?(PropertyDamage.Mutation.Report.t()) :: boolean()
Checks if a mutation report passes the target score.
Examples
if PropertyDamage.Mutation.passes?(report) do
IO.puts("Tests are effective!")
end
@spec run(keyword()) :: {:ok, PropertyDamage.Mutation.Report.t()} | {:error, term()}
Runs mutation testing against a model.
Returns {:ok, report} with mutation testing results.
Examples
{:ok, report} = PropertyDamage.Mutation.run(
model: MyModel,
adapter: MyAdapter,
operators: [:value, :omission],
target_score: 0.80
)
report.mutation_score # => 0.85
report.killed # => 17
report.survived # => 3
@spec weakest_commands(PropertyDamage.Mutation.Report.t()) :: [ {module(), PropertyDamage.Mutation.Report.command_stats()} ]
Returns the weakest commands from a report, sorted by kill rate.
Examples
for {cmd, stats} <- PropertyDamage.Mutation.weakest_commands(report) do
IO.puts("#{cmd}: #{stats.score * 100}%")
end
@spec weakest_operators(PropertyDamage.Mutation.Report.t()) :: [ {atom(), PropertyDamage.Mutation.Report.command_stats()} ]
Returns the weakest operators from a report, sorted by kill rate.