
rustkas
Journal: Property-Based Testing with PropEr, Erlang, and Elixir
To be a more productive reader when rereading a book, it is very convenient to create small rebar3 projects based on books’ samples and ideas. Here’s what I’ve already made.
Most Liked

rustkas
Exercise 2
I add output and then run it to see it execute.
There is peace of my code with output:
increments([Head | Tail]) -> increments(Head, Tail).
increments(_, []) ->
io:format("~n"),
true;
increments(N, [Head | Tail]) when Head == N + 1 ->
io:format("~p", [Head]),
if length(Tail) > 0 -> io:format(", ");
true -> io:format("|")
end,
increments(Head, Tail);
increments(_, _) -> false.

rustkas
Erlang
(page 88)
code/CustomGenerators/erlang/pbt/test/prop_generators.erl
I would like to share inner step calculation while gathering values (by groups of 10). I was confused a litter how is the calculation going.
I have inserted an expression to print the parameters.
prop_collect2() ->
?FORALL(Bin, (binary()),
(collect(to_range(10, byte_size(Bin)),
is_binary(Bin)))).
%%%%%%%%%%%%%%%
%%% Helpers %%%
%%%%%%%%%%%%%%%
to_range(M, N) ->
Base = N div M,
io:format("~2B = ~2B div ~B | {~2B, ~B} = {~2B * ~B, (~B + 1)*~B~n",
[Base, N, M, Base * M, (Base + 1) * M, Base, M, Base, M]),
{Base * M, (Base + 1) * M}.
Command:
rebar3 proper -p prop_collect2
Output (with the intermediate calculations):
0 = 0 div 10 | { 0, 10} = { 0 * 10, (0 + 1)*10
. 0 = 1 div 10 | { 0, 10} = { 0 * 10, (0 + 1)*10
. 0 = 0 div 10 | { 0, 10} = { 0 * 10, (0 + 1)*10
. 0 = 0 div 10 | { 0, 10} = { 0 * 10, (0 + 1)*10
...
. 3 = 38 div 10 | {30, 40} = { 3 * 10, (3 + 1)*10
. 3 = 33 div 10 | {30, 40} = { 3 * 10, (3 + 1)*10
. 1 = 15 div 10 | {10, 20} = { 1 * 10, (1 + 1)*10
. 2 = 22 div 10 | {20, 30} = { 2 * 10, (2 + 1)*10
OK: Passed 100 test(s).
56.00% {0,10}
28.00% {10,20}
9.00% {20,30}
7.00% {30,40}
===>
1/1 properties passed

rustkas
Erlang
(page 89)
code/CustomGenerators/erlang/pbt/test/prop_generators.erl
While running property based test prop_dupes
you will get the same logging info.
prop_dupes() ->
?FORALL(KV, list({key(), val()}),
begin
M = maps:from_list(KV),
_ = [maps:get(K, M) || {K, _V} <- KV], % crash if K's not in map
collect(
{dupes, to_range(5, length(KV) - length(lists:ukeysort(1,KV)))},
true
)
end).
%%%%%%%%%%%%%%%
%%% Helpers %%%
%%%%%%%%%%%%%%%
key() -> integer().
val() -> term().
to_range(M, N) ->
Base = N div M,
io:format("~2B = ~2B div ~B | {~2B, ~2B} = {~2B * ~B, (~B + 1)*~B~n",
[Base, N, M, Base * M, (Base + 1) * M, Base, M, Base, M]),
{Base * M, (Base + 1) * M}.
Full code project
Popular General Dev topics









Other popular topics










Latest in General Dev
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /ash
- /centos
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /textmate
- /sublime-text
- /react-native
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /manjaro
- /django
- /spring
- /diversity
- /nodejs
- /lua
- /julia
- /c
- /slackware
- /neovim