Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Property-based testing is a mindset

Property-based testing is a mindset

Andrea Leopardi

April 17, 2018
Tweet

More Decks by Andrea Leopardi

Other Decks in Programming

Transcript

  1. I S A M I N D S E T

    P R O P E R T Y - B A S E D T E S T I N G
  2. test "sorting" do assert sort([]) == [] assert sort([1, 2,

    3]) == [1, 2, 3] assert sort([2, 1, 3]) == [1, 2, 3] end example-based
  3. test "sorting" do assert sort([]) == [] assert sort([1, 2,

    3]) == [1, 2, 3] assert sort([2, 1, 3]) == [1, 2, 3] end
  4. check all list <- list_of(int()) do sorted = sort(list) assert

    is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
  5. check all list <- list_of(int()) do sorted = sort(list) assert

    is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
  6. check all list <- list_of(int()) do sorted = sort(list) assert

    is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
  7. check all list <- list_of(int()) do sorted = sort(list) assert

    is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
  8. check all list <- list_of(int()) do sorted = sort(list) assert

    is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
  9. bind_filter(integer(), fn i -> if i < 0 do :skip

    else gen = map(list_of(integer()), &(&1 + i)) {:cont, gen} end end) bind_filter (possibly) creates generators from generated terms
  10. property "unicode escaping" do check all string <- string(:printable) do

    encoded = encode(string, escape: :unicode) assert decode(encoded) == string end end JSON encoding
  11. property "gives same results as Erlang impl" do check all

    bin <- binary() do assert Huffman.encode(bin) == :huffman.encode(bin) end end
  12. https://www.youtube.com/watch?v=jvwfDdgg93E property "only expected codes are returned" do check all

    request <- request() do response = HTTP.perform(request) assert response.status in [200, 201, 400, 404] end end
  13. property "String.contains?/2" do check all left <- string(), right <-

    string() do assert String.contains?(left <> right, left) assert String.contains?(left <> right, right) end end test "String.contains?/2" do assert String.contains?("foobar", "foo") assert String.contains?("foobar", "bar") assert String.contains?("foobar", "ob") end +
  14. {:ok, result} = Redix.command!(conn, ["GET", key]) assert Map.fetch(model, key) ==

    {:ok, result} Redix.command!(conn, ["SET", key, value]) Map.replace!(model, key, value) get set_existing
  15. defmodule Tree do def tree() do StreamData.tree(:leaf, fn leaf ->

    {leaf, leaf} end) end def size({l, r}), do: 1 + size(l) + size(r) def size(_leaf), do: 1 def depth({l, r}), do: 1 + max(depth(l), depth(r)) def depth(_leaf), do: 1 end
  16. Generation size: 10 Avg size: 4.9 Avg max depth: 2.473

    Generation size: 100 Avg size: 10.892 Avg max depth: 3.466 Generation size: 1000 Avg size: 22.732 Avg max depth: 4.507
  17. @spec my_fun(timeout()) :: :ok | :error check all timeout <-

    from_type(timeout()) do assert my_fun(timeout) in [:ok, :error] end