TDD básico com Eunit
TDD é uma técnica essencial no desenvolvimento de software atual. Além de conseguir-se testes expressivos, a qualidade e design do código aumentam bastante. Na linguagem Erlang também é possível utilizar a técnica do TDD com a ferramenta Eunit. Será apresentado um guia, com alguns passos, sobre como testar uma aplicação Erlang utilizando Eunit.
Passo 1: criar a estrutura do projeto
O nome do projeto será making_tdd_with_eunit. Tem-se então a seguinte estrutura de diretórios, que é frequentemente encontrada em projetos Erlang:
- making_tdd_with_eunit |
+-- ebin+-- src
+-- test
Apesar dos diretórios terem nomes bem auto explicativos, eles tem o seguinte significado:
- ebin, conterão os binários (.beam) resultantes da compilação dos fontes;
- src, conterão os fontes (.erl) dos módulos;
- test, conterão os fontes (.erl) dos testes.
Passo 2: escrever o primeiro teste que intencionalmente falhará
No diretório test, deve ser criado o seguinte teste (mobile_test.erl):
%%
%% mobile_test.erl
%%
-module(mobile_test).
-include_lib("eunit/include/eunit.hrl").
describe_client_test_() ->
{"Mobile",
[fun should_have_a_number/0]}.should_have_a_number() ->
?assertMatch({number, _}, mobile:number()).
Feito isso, compile e rode o teste com os seguintes comandos:
$ erlc -o ebin/ test/mobile_test.erl
$ erl -pa ebin/ -noshell -run mobile_test test -run init stop
O teste falhou como mandam as regras do TDD e assim como Kent Back diz em seu livro TDD By Example:
Escreva um teste, rode todos os testes e veja-o falhar; escreva o código mais simples possível para fazê-lo passar, mesmo que num primeiro momento não seja o mais bonito e eficiente; rode todos os testes e veja-os passar; depois, refatore para remover duplicações.
Passo 3: fazer o primeiro teste passar com o código mais simples possível
No diretório src, deve ser criado o seguinte módulo (mobile.erl):
%% %% mobile.erl %% -module(mobile). -export([number/0]).number() ->
{number, "1212-1212"}.
Como feito anteriormente – no entanto, agora acrescentando o módulo mobile à compilação –, compile e rode o teste com os seguintes comandos:
$ erlc -o ebin/ src/mobile.erl test/mobile_test.erl
$ erl -pa ebin/ -noshell -run mobile_test test -run init stop
Passo 4: escrever mais testes
Agora será mostrado o ponto em que magicamente passa-se a ter testes para as quatro funções contidas no módulo mobile.
%% %% mobile_test.erl %% -module(mobile_test).-include_lib("eunit/include/eunit.hrl").
describe_client_test_() ->
{"Mobile",
[fun should_have_a_number/0,
fun should_have_a_area_code/0,
fun should_have_a_company/0,
fun should_have_a_owner/0]}.should_have_a_fixed_number() ->
?assertMatch({number, "1212-1212"}, mobile:number()).should_have_a_fixed_area_code() ->
?assertMatch({area_code, "11"}, mobile:area_code()).should_have_a_fixed_company() ->
?assertMatch({company, "DEAD"}, mobile:company()).should_have_a_fixed_owner() ->
?assertMatch({owner, "Little Jose"}, mobile:owner()).
%%
%% mobile.erl
%%
-module(mobile).-export([number/0, area_code/0, company/0, owner/0]).
number() ->
{number, "1212-1212"}.area_code() ->
{area_code, "11"}.company() ->
{company, "DEAD"}.owner() ->
{owner, "Little Jose"}.
Agora deve-se compilar e rodar os testes para ver o resultado obtido. Isso deve ser feito da seguinte maneira:
$ erlc -o ebin/ src/mobile.erl test/mobile_test.erl
$ erl -pa ebin/ -noshell -run mobile_test test -run init stop
Todos os testes estão passando e agora é o momento de fazer algumas refatorações.
Passo 5: refatorar os testes para ficarem mais fluentes
Nesse ponto, não há muito o que mudar nos testes, não há exatamente nenhuma duplicação de código e dados a ser refatorado, simplificada, nada ainda. Mas será adicionada mais fluência aos testes e visando melhorar sua comunicação, inclusive, descrevendo um cenário “mais interessante”.
%%
%% mobile_test.erl
%%
-module(mobile_test).-include_lib("eunit/include/eunit.hrl").
describe_client_test_() ->
{"Mobile",
{"when is a dummy",
[
{"should have a fixed number", fun should_have_a_fixed_number/0},
{"should have a fixed area code", fun should_have_a_fixed_area_code/0},
{"should have a fixed company", fun should_have_a_fixed_company/0},
{"should have a fixed owner", fun should_have_a_fixed_owner/0} ]}}.should_have_a_fixed_number() ->
?assertMatch({number, "1212-1212"}, mobile:number()).should_have_a_fixed_area_code() ->
?assertMatch({area_code, "11"}, mobile:area_code()).should_have_a_fixed_company() ->
?assertMatch({company, "DEAD"}, mobile:company()).should_have_a_fixed_owner() ->
?assertMatch({owner, "Little Jose"}, mobile:owner()).
Próximo passo: escrever mais testes e refatorar o módulo mobile
Até aqui, existe um módulo mobile totalmente dummy e um teste que usa apenas a macro ?assertMatch. Ainda há muito que pode ser feito, desde adicionar algum comportamento realmente útil ao módulo mobile, até melhorar os testes fazendo diferentes asserções, adicionando befor_all e after_all (como nos testes do Restfulierl, por exemplo) para estado inicial e final.
Você pode achar mais sobre Erlang e Eunit no blog CødeZøne!.
O passo 4 está errado
by
Adolfo Neto
%%
%% mobile_test.erl
%%
-module(mobile_test).
-include_lib("eunit/include/eunit.hrl").
describe_client_test_() ->
{"Mobile",
[fun should_have_a_fixed_number/0,
fun should_have_a_fixed_area_code/0,
fun should_have_a_fixed_company/0,
fun should_have_a_fixed_owner/0]}.
should_have_a_fixed_number() ->
?assertMatch({number, "1212-1212"}, mobile:number()).
should_have_a_fixed_area_code() ->
?assertMatch({area_code, "11"}, mobile:area_code()).
should_have_a_fixed_company() ->
?assertMatch({company, "DEAD"}, mobile:company()).
should_have_a_fixed_owner() ->
?assertMatch({owner, "Little Jose"}, mobile:owner()).
Conteúdo educacional
Mobilidade: Frameworks, SOs e o Mercado
Ricardo Ogliari 23 Mai, 2013
Caminhos de uma estratégia mobile
Sérgio Lopes 23 Mai, 2013
Complexidade organizacional no Século 21
Alexandre Magno 16 Mai, 2013

Olá visitante
Você precisa cadastrar-se no InfoQ Brasil ou Login para enviar comentários. Há muitas vantagens em se cadastrar.Obtenha o máximo da experiência do InfoQ Brasil.
Dê sua opinião