Uma das coisas mais legais em Elixir é a facilidade para criar e executar testes automatizados (testes que são escritos como código).
Com isso, você pode fazer TDD (Test-Driven Development ou Desenvolmento Guiado por Testes) com facilidade. Não sabe o que é TDD? Leia o livro do Maurício Aniche!
O que vou mostrar aqui é o passo-a-passo para fazer TDD em Elixir.
Passo 1: Criar o projeto
Uma vez tendo o Elixir instalado, você vai num terminal (no meu caso, um Ubuntu 20.04 dentro do WSL do Windows 10), e digita mix new <nome do projeto>. No caso abaixo, o nome do projeto é calculadora.
elixir@utfpr:~/DevTo$ mix new calculadora * creating README.md * creating .formatter.exs * creating .gitignore * creating mix.exs * creating lib * creating lib/calculadora.ex * creating test * creating test/test_helper.exs * creating test/calculadora_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd calculadora mix test Run "mix help" for more commands.
Pronto. O mix criou a pasta calculadora e dentro desta as pastas lib e test. Ou seja, o mix já separou para você o código que tem funcionalidades (pasta lib) do código de testes (pasta test). Além disso ele criou 5 arquivos. Os arquivos relevantes para nosso exemplo simples são apenas lib/calculadora.ex e test/calculadora_test.exs.
Passo 2 - Rodar os Testes
Veja na imagem acima que o mix sugere que você, logo após a criação do projeto, vá para a pasta do novo projeto, calculadora, e execute os testes. Sim, o mix já cria testes para você.
Vamos primeiro então rodar os testes que o mix criou:
elixir@utfpr:~/DevTo$ cd calculadora elixir@utfpr:~/DevTo/calculadora$ mix test Compiling 1 file (.ex) Generated calculadora app .. Finished in 0.08 seconds 1 doctest, 1 test, 0 failures Randomized with seed 652059 elixir@utfpr:~/DevTo/calculadora$
Olha que legal! Passou em todos os testes! OK, só tem dois testes: um doctest e um teste normal.
Passo 3: Remover o doctest
Vamos dar uma espiada nos arquivos gerados? Importante: estou usando o Elixir 1.11.2. Diferentes versões podem ter conteúdos diferentes nos arquivos gerados.
Arquivo lib/calculadora.ex:
defmodule Calculadora do @moduledoc """ Documentation for `Calculadora`. """ @doc """ Hello world. ## Examples iex> Calculadora.hello() :world """ def hello do :world end end
Como aqui estamos tratando do básico, eu vou apagar o doctest, ou seja, tudo que está entre @doc """ e """.
Arquivo lib/calculadora.ex passa a ser:
defmodule Calculadora do @moduledoc """ Documentation for `Calculadora`. """ def hello do :world end end
Rodemos os testes de novo:
elixir@utfpr:~/DevTo/calculadora$ mix test Compiling 1 file (.ex) . Finished in 0.03 seconds 1 test, 0 failures Randomized with seed 900374 elixir@utfpr:~/DevTo/calculadora$
Pronto. Agora só temos um teste.
Passo 4: Escrever o seu primeiro teste
Vamos dar uma olhada no teste? Está em test/calculadora_test.exs.
Isto é importante! O arquivo deve estar na pasta test/ e seu nome deve terminar em _test.exs. Se não for assim, o arquivo contendo os testes não vai ser encontrado pela biblioteca que roda os testes.
Arquivo test/calculadora_test.exs:
defmodule CalculadoraTest do use ExUnit.Case doctest Calculadora test "greets the world" do assert Calculadora.hello() == :world end end
Como vemos acima, o teste gerado pelo mix tem descrição "greets the world" (tradução: "cumprimenta o mundo").
O único comando deste teste é um assert. Ele afirma (a tradução do Google Translate para assert) que se eu chamar a função hello() do módulo Calculadora, o resultado vai ser igual (==) ao átomo :world.
O teste que escreveremos simplesmente afirma que 2 + 2 = 4:
test "2+2 é 4" do assert Calculadora.soma(2,2) == 4 end
Com este teste, o arquivo test/calculadora_test.exs passa a ser:
defmodule CalculadoraTest do use ExUnit.Case doctest Calculadora test "greets the world" do assert Calculadora.hello() == :world end test "2+2 é 4" do assert Calculadora.soma(2,2) == 4 end end
Uma das práticas de TDD é rodar os testes mesmo quendo você espera que eles falhem, como será o caso abaixo pois sequer criamos a função Calculadora.soma/2.
Rodemos os testes de novo:
elixir@utfpr:~/DevTo/calculadora$ mix test warning: Calculadora.soma/2 is undefined or private test/calculadora_test.exs:10: CalculadoraTest."test 2+2 é 4"/1 . 1) test 2+2 é 4 (CalculadoraTest) test/calculadora_test.exs:9 ** (UndefinedFunctionError) function Calculadora.soma/2 is undefined or private code: assert Calculadora.soma(2,2) == 4 stacktrace: (calculadora 0.1.0) Calculadora.soma(2, 2) test/calculadora_test.exs:10: (test) Finished in 0.3 seconds 2 tests, 1 failure elixir@utfpr:~/DevTo/calculadora$
Os testes falharam? Ótimo. Era o esperado.
Passo 5: Fazer o teste passar usando Passos de Bebê.
A técnica Passos de Bebê (Baby Steps) sugere que você escreva o mínimo necessário para passar no teste. Neste caso, o mínimo necessário é escrever a função Calculadora.soma/2 ignorando seus parâmetros e retornando 4:
def soma(_,_), do: 4
Arquivo lib/calculadora.ex passa a ser:
defmodule Calculadora do @moduledoc """ Documentation for `Calculadora`. """ def hello do :world end def soma(_,_), do: 4 end
Rodemos os testes de novo:
elixir@utfpr:~/DevTo/calculadora$ mix test Compiling 1 file (.ex) .. Finished in 0.03 seconds 2 tests, 0 failures Randomized with seed 371832 elixir@utfpr:~/DevTo/calculadora$
Passo 6: Escrever o seu segundo teste
O segundo teste que escreveremos afirma que 3 + 3 = 6:
test "3+3 é 6" do assert Calculadora.soma(3,3) == 6 end
Com este teste, o arquivo test/calculadora_test.exs passa a ser:
defmodule CalculadoraTest do use ExUnit.Case doctest Calculadora test "greets the world" do assert Calculadora.hello() == :world end test "2+2 é 4" do assert Calculadora.soma(2,2) == 4 end test "3+3 é 6" do assert Calculadora.soma(3,3) == 6 end end
Rodemos os testes de novo:
elixir@utfpr:~/DevTo/calculadora$ mix test .. 1) test 3+3 é 6 (CalculadoraTest) test/calculadora_test.exs:13 Assertion with == failed code: assert Calculadora.soma(3, 3) == 6 left: 4 right: 6 stacktrace: test/calculadora_test.exs:14: (test) Finished in 0.06 seconds 3 tests, 1 failure Randomized with seed 966924 elixir@utfpr:~/DevTo/calculadora$
Vejam que agora a mensagem de erro é diferente. O teste esperava 6 mas a função retornou 4.
Como fazer o teste passar?
Agora basta implementar de fato a função Calculadora.soma/2:
def soma(num1, num2), do: num1 + num2
Arquivo lib/calculadora.ex passa a ser:
defmodule Calculadora do @moduledoc """ Documentation for `Calculadora`. """ def hello do :world end def soma(num1, num2), do: num1 + num2 end
Rodemos os testes de novo:
elixir@utfpr:~/DevTo/calculadora$ mix test Compiling 1 file (.ex) ... Finished in 0.03 seconds 3 tests, 0 failures Randomized with seed 498106 elixir@utfpr:~/DevTo/calculadora$
Passou em todos os testes!
OK, acho que por hoje é só. Daqui vocês já podem continuar.
Vejam que não deu tempo de falar de refatoração nem das diversas formas de afirmar/refutar usando ExUnit, o arcabouço (framework) de testes de unidade do Elixir.
E então, o que vocês querem saber mais sobre Elixir?
PS: um vídeo relacionado
Top comments (0)