Skip to content

Test shrinking #160

Open
Open
@Qqwy

Description

@Qqwy

While working on the PR for #129, I encountered # TODO: test shrinking at the top of the StreamDataTest module.

Since there is no open issue for it, it seemed like a good idea to open it so it is not forgotten, we can discuss how this might be approached, and maybe someone can contribute a PR.


One approach might be to add a function StreamData.shrink([max_shrinking_steps: 100, initial_seed: :os.timestamp()]).
Its implementation might look like follows:

def shrink(options) when is_list(options) do
  max_shrinking_steps = Keyword.get(options, :max_shrinking_steps, 100)
  initial_seed = Keyword.get(options, :initial_seed, :os.timestamp()) # Or obtained from ExUnitProperties if set during a test run.

    {:error, %{shrunk_value: value}} = 
      check_all(StreamData.integer(), [max_shrinking_steps: max_shrinking_steps, initial_seed: initial_seed], &{:error, &1})
  value
end

(Side note: If desired, it might be optimized somewhat by instead hooking into the internals of StreamData.check_all/3 rather than calling it from the outside.)

This could then be used in a higher-order property test (a property test which builds and tests a generator).
An example:

  describe "integer/1" do
    property "shrinks towards smallest value still in range" do
      check all bound1 <- integer(),
                bound2 <- integer() do
        generator = integer(bound1..bound2)
        assert shrink(generator) == min(bound1, bound2)
      end
    end
end

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions