ExFuzz (ExFuzz v0.1.0)

Copy Markdown View Source

Coverage-guided fuzz testing for Elixir.

defmodule JasonTest do
  use ExUnit.Case
  use ExFuzz

  @tag timeout: 100
  fuzz "Jason never crashes", data <- binary(), seeds: ["{}", "[1]"] do
    with {:ok, term} <- Jason.decode(data) do
      assert Jason.decode!(Jason.encode!(term)) == term
    end
  end
end

Fuzz tests run alongside your regular ExUnit tests, using the seed corpus as an ever-growing regression suite. Run only them with mix test --only fuzz.

To start fuzzing a target, point mix fuzz at the test by line or name:

$ mix fuzz test/jason_test.exs:6
$ mix fuzz test/jason_test.exs:"fuzz Jason never crashes"

Failing inputs are saved as seed corpus to test/fixtures/fuzz/ and replayed by mix test from then on. You can configure this with :corpus_dir under the :ex_fuzz key of your project config.

Summary

Functions

Defines a fuzz test with message, running its body as the target, once per input.

Functions

fuzz(message, input, context \\ quote do _ end, opts \\ [], contents)

(macro)

Defines a fuzz test with message, running its body as the target, once per input.

The test may also define a pattern, which will be matched against the test context.

Options

  • :seeds - example inputs that fuzzing starts from, part of the seed corpus.

Examples

fuzz "Jason never crashes", data <- binary(), seeds: ["{}", "[1]"] do
  with {:ok, term} <- Jason.decode(data) do
    assert Jason.decode!(Jason.encode!(term)) == term
  end
end

You can start fuzzing the target using mix fuzz:

$ mix fuzz test/jason_test.exs:"fuzz Jason never crashes"