Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

** (FunctionClauseError) no function clause matching in :proper_arith.rand_choose/1 #221

Open
coop opened this issue May 17, 2023 · 3 comments

Comments

@coop
Copy link

coop commented May 17, 2023

Hi,

I'm seeing this error ** (FunctionClauseError) no function clause matching in :proper_arith.rand_choose/1 while running my test. I assume the problem is one of my generators are failing but there isn't enough information to determine which generator.

I'm hoping that a better error message can be raised that can help target which generator is failing.

This is the stacktrace:

✦ ❯ mix test test/property_test.exs 
22:09:26.189 [info] Running VendWeb.Endpoint with cowboy 2.10.0 at :::4012 (http)
22:09:26.193 [info] Access VendWeb.Endpoint at http://localhost:4012
..........

  1) property it works (Vend.PropertyTest)
     test/property_test.exs:15
     ** (FunctionClauseError) no function clause matching in :proper_arith.rand_choose/1

     The following arguments were given to :proper_arith.rand_choose/1:
     
         # 1
         []
     
     stacktrace:
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_arith.erl:342: :proper_arith.rand_choose/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:491: :proper_gen.union_gen/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:198: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:557: :proper_gen."-fixed_list_gen/1-lc$^1/1-0-"/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:557: :proper_gen."-fixed_list_gen/1-lc$^1/1-0-"/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:198: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:557: :proper_gen."-fixed_list_gen/1-lc$^1/1-0-"/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:557: :proper_gen."-fixed_list_gen/1-lc$^1/1-0-"/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:524: :proper_gen.tuple_gen/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:198: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:198: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:186: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:198: :proper_gen.generate/3
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:136: :proper_gen.generate/1
       (proper 1.4.0) /Users/dad/Code/youtooz/vend/vend-firmware/fw/deps/proper/src/proper_gen.erl:200: :proper_gen.generate/3


Finished in 96.8 seconds (0.00s async, 96.8s sync)
1 property, 1 failure

Randomized with seed 210523

Elixir: 1.14.3
Erlang: 25.2.2
PropCheck 1.4.1

@alfert
Copy link
Owner

alfert commented May 18, 2023

That looks really bad. The error message usually appears when the generator tries to select something from an empty collection such as one_of([]). If you combine many generators it is important to not forget that these combinations are really higher order combinations of functions and not function calls. Depending on your experience and the complexity of a generator this can easily slip through.

Did you try to use the sampling functions produce to test your generator? Typically, you would use that from an IEx session to inspect generators. It might be helpful to really check the trivial generators and then move up the ladder to more complex ones like the union you have in your stack trace.

@coop
Copy link
Author

coop commented May 18, 2023

@alfert the failing generator ending up being something like the following:

def some_value(state) do
  oneof(Map.keys(state.some_map))
end

and state.some_map was an empty map.

I've found it hard to test these generators in a console because they rely on building up state via next_state/3. I assume it's impossible to say but am I "doing it wrong"?

Is there any way to provide more context in the stacktrace to narrow down where the error is coming from?

@alfert
Copy link
Owner

alfert commented May 19, 2023

@coop Indeed, difficult to give a good advice w/o knowing your system or your test setup in more detail. But if I meditate about this issue and #217 then I come these general ideas which might be totally obvious and/or helpful:

Your state-dependent generators should we very aware of the state. Here something like

def some_value(state) where not(Map.empty? (state.some_map)) do
   ...
end

I find it sometimes helpful to have an abstract state enumeration (e.g. :init, :no_clients, :working, :overloaded) that direct
which generators can be used. Modeling your system in such abstract states helps to think about your more fundamental states and which generators (and pre/post conditions) are appropriate for these states.

Generally, I think it is more an art than a science to come up with a model that is easy to analyse and provokes enough interesting test situations to torture the system under test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants