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

Mantendo a Sanidade Testando Estado

Mantendo a Sanidade Testando Estado

Apesar de ser uma ferramenta poderosa, Teste Baseado em Propriedades é muito pouco aplicado. Vou falar um pouco sobre a técnica e seus trade-offs, ferramentas para Elixir e contar um pouco sobre como estamos aplicando em nossos micro-serviços, stateful.

Andrew Rosa

May 26, 2019
Tweet

More Decks by Andrew Rosa

Other Decks in Programming

Transcript

  1. test "sorts an empty list" test "sorts a list with

    a single item" test "sorts a list multiple equal items" test "sorts a list huge numbers" test "sorts a list negative numbers" test "sorts a big list with lots of items"
  2. property "sorts a list" do forall x <- list(integer()) do

    Enum.sort(x) |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a <= b end) end end
  3. property "sorts a list" do forall x <- list(integer()) do

    Enum.sort(x) |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a <= b end) end end
  4. property "sorts a list" do forall x <- list(integer()) do

    Enum.sort(x) |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a <= b end) end end
  5. property "sorts a list" do forall x <- list(integer()) do

    Enum.sort(x) |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a <= b end) end end
  6. property "sorts a list" do forall unsorted <- list(integer()) do

    unsorted |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a <= b end) end end
  7. forall cmds <- commands(TestModel) do {history, state, result} = run_commands(TestModel,

    cmds) (result == :ok) |> aggregate(command_names(cmds)) |> when_fail(& report(cmds, state, result, history)) end
  8. forall cmds <- commands(TestModel) do {history, state, result} = run_commands(TestModel,

    cmds) (result == :ok) |> aggregate(command_names(cmds)) |> when_fail(& report(cmds, state, result, history)) end
  9. V1

  10. def next_state(state, call_id, {:call, _, :dial, [number]}) do state |>

    acquire_call(call_id, number) |> set_call_state(call_id, :ringing) end
  11. forall cmds <- commands(TestModel) do {history, state, result} = run_commands(TestModel,

    cmds) (result == :ok) |> aggregate(command_names(cmds)) |> when_fail(& report(cmds, state, result, history)) end
  12. defmodule TestShim do def dial(number) do # build client and

    payload
 case Tesla.post(client, "/dial", payload) do # process response and return call_id end end end
  13. def handle_call({:command, :dial, number}, from, state) do {:ok, call_id} =

    CallControl.dial(number) # update state {:noreply, state} end
  14. def handle_cast({:webhook, webhook, call_id, resp}, state) do # descobre `ref`

    a partir dos parâmetros if ref, do: GenServer.reply(ref, resp) {:noreply, state} end
  15. forall cmds <- commands(TestModel) do TestShim.setup_parties() {history, state, result} =

    run_commands(TestModel, cmds) (result == :ok) |> aggregate(command_names(cmds)) |> when_fail(& report(cmds, state, result, history)) end
  16. forall cmds <- commands(TestModel) do TestShim.setup_parties() {history, state, result} =

    run_commands(TestModel, cmds) (result == :ok) |> aggregate(command_names(cmds)) |> when_fail(& report(cmds, state, result, history)) end
  17. ROI