Skip to content

Propcheck options like numtests not considered until performing mix propcheck.clean #152

@turion

Description

@turion

Short description

Adding the numtests: some_number option to a property has no effect until MIX_ENV=test mix propcheck.clean is run.

To reproduce

  1. Write a test that fails when run multiple times (e.g. using a resource that is tainted after use)
  2. Add numtests: 1
  3. Be surprised it still fails

Long description with MWE

Consider this test module:

defmodule FooTest do
  use ExUnit.Case
  use PropCheck

  setup do
    Application.ensure_all_started(:propcheck)
    {:ok, resource} = Agent.start_link(fn -> :pristine end, name: :AgentFoo)
    [resource: resource]
  end

  property "foo", [:verbose], ctx do
    forall _ <- PropCheck.BasicTypes.integer() do
      agent_state = Agent.get(ctx.resource, & &1)
      Agent.update(ctx.resource, fn _ -> :tainted end)
      equals(agent_state, :pristine)
    end
  end
end

It contains a test setup that launches an Agent which we suppose necessary for testing. When performing a test, this resource is tainted, and cannot be used anymore:

$ mix test
OK: The input passed the test.
!
Failed: After 1 test(s).
1
:tainted != :pristine

Shrinking .(1 time(s))
0
:tainted != :pristine


  1) property foo (FooTest)
     test/foo_test.exs:11
     Property Elixir.FooTest.property foo() failed. Counter-Example is:
     [0]
     
     Counter example stored.
     
     code: nil
     stacktrace:
       (propcheck) lib/properties.ex:206: PropCheck.Properties.handle_check_results/4
       test/foo_test.exs:11: (test)



Finished in 0.06 seconds
1 property, 1 failure

Randomized with seed 417964

To work around this issue, we want to limit the number of tests to 1. We change the property line to:

  property "foo", [:verbose, numtests: 1], ctx do

Weirdly, this has no effect. The test is still executed several times and of course still fails:

$ mix test
OK: The input passed the test.
!
Failed: After 1 test(s).
0
:tainted != :pristine

Shrinking (0 time(s))
0
:tainted != :pristine

[...]

Strange. Because it has become muscle memory when something in propcheck doesn't work, let's clean generators:

$ MIX_ENV=test mix propcheck.clean

Now it works miraculously:

$ mix test
.
OK: Passed 1 test(s).
.

Finished in 0.04 seconds
1 property, 0 failures

Randomized with seed 602259

I find this behaviour very surprising.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions