You are on page 1of 58

Palestra Caf com Tapioca: Testes de Unidade com Junit

Instrutor: Fabrcio Lemos

15/12/2007

Agenda

Conceito de Testes de Unidade Junit EasyMock DbUnit Desenvolvimento Guiado por Testes - TDD

Testes de So t!are

" um t#pico importante e vital no desenvolvimento de so t!are Todo mundo sabe $ue testes precisam ser eitos E%iste uma $uantidade enorme de aspectos $ue precisam ser testados em um sistema

Testes de So t!are

& sistema deve passar por diversos tipos de teste antes de entrar em produ'(o

Unidade )ntegra'(o *uncional Stress e per ormance Aceita'(o

Testes de So t!are

" praticamente imposs+vel evitar $ue erros se,am inseridos no c#digo


Atividade comple%a Manipula uma grande $uantidade de elementos abstratos )nclus-es de novas uncionalidades podem in luenciar nas ,. e%istentes Muitas ve/es 0 di +cil ter certe/a $ue o c#digo est. totalmente correto at0 $ue ele se,a e%ecutado Geralmente os desenvolvedores do pro,eto possuem di erentes n+veis de 1abilidades

Testes de So t!are

Mesmo tendo recon1ecida import2ncia no desenvolvimento de so t!are3 os teste costumam ser vistos como uma atividade c1ata e repetitiva

S# costumam receber aten'(o $uando os problemas come'am a ser tornar comuns

Geralmente s# s(o iniciados $uando o produto est. todo 4pronto5

Testes de So t!are

Muitos pro,etos assumem $ue o c#digo desenvolvido est. livre de erros e postergam os testes para as ases inais do desenvolvimento

6re erem remediar do $ue prevenir 4Est. tudo pronto3 s# alta testar5

Testando o C#digo da Aplica'(o

Como ter certe/a de $ue o c#digo escrito a/ o $ue deveria a/er e n(o cont0m erros7 Abordagens comumente usadas

Escreve-se um m0todo main $ue c1ama o m0todo escrito e veri ica-se o retorno Espera-se $ue a uncionalidade este,a pronta e reali/ase um teste uncional manual 8(o 0 poss+vel a reali/a'(o de testes de regress(o

&s testes s(o eitos de maneira pontual

Testando o C#digo da Aplica'(o

Testes n(o s(o automati/ados

8(o 0 poss+vel utili/a-los na integra'(o cont+nua

8(o s(o gerados relat#rios sobre a e%ecu'(o dos testes Testes n(o s(o e%ecutados de maneira isolada

Maior di iculdade em encontrar a onte de um erro

8(o 1. disciplina para a reali/a'(o dos testes

Testes de Unidade

E%aminam o comportamento de uma 4unidade de trabal1o5 distinta

Em ,ava3 geralmente representada por um 9nico m0todo

Unidades de trabal1o s(o testadas de maneira isolada 6ossuem nature/a di erente dos testes de integra'(o e de aceita'(o

e%aminam como v.rios componentes interagem

&b,etivos

:eri icar se um peda'o de c#digo a/ o $ue o desenvolvedor ac1a $ue ele a/ :eri icar se um peda'o de c#digo SEM6;E a/ o $ue o desenvolvedor ac1a $ue ele a/ )denti icar bugs prematuramente 6ermitir $ue novas uncionalidades se,am adicionadas sem comprometer as ,. e%istentes Diminuir o impacto das re atora'-es de c#digo

:antagens dos Testes de Unidade


6ermite uma grande cobertura dos testes 6ode acilmente simular condi'-es de erro Mel1ora o trabal1o em e$uipe

6ermite ao desenvolvedor entregar c#digo de $ualidade <testado= sem esperar $ue outras partes este,am prontas 4Algu0m5 assistindo a altera'(o>inclus(o de novas uncionalidades

D.-l1e a con ian'a $ue seu c#digo unciona

:antagens

Diminui o tempo gasto com depura'(o de c#digo

?uando 1. algum erro3 te di/ o m0todo $ue al1ou e o motivo da al1a Testes de unidade s(o os primeiros 4clientes5 do c#digo Aprendi/agem por e%emplos

Mel1ora a implementa'(o

Serve como uma documenta'(o do c#digo

:antagens

S(o acilmente incorporados na )ntegra'(o Cont+nua ;elat#rios sobre a corretude do c#digo e a cobertura dos testes s(o gerados de maneira autom.tica

Junit

*rame!ork de teste criado por Eric1 Gamma e @ent Aeck 6ossui uma api bastante .cil e simples ;apidamente se tornou o rame!ork padr(o para testes em Java 6ossui suporte para diversas erramentasB Eclipse3 Maven3 Ant3 etcCCCC

Junit

*oram desenvolvidas diversas e%tens-es para acilitar os testes de partes espec+ icas de um pro,eto

EasyMock DbUnit StrutsTestCase Cactus S1ale Test *rame!ork etcCCC

Escrevendo os Testes
public class Calculadora { public int somar(int op1, int op2) { return op1 + op2; } }

Escrevendo os Testes
import static org.junit.Assert.*; import org.junit. est; public class estCalculadora {

! est public "oid test#omar() { Calculadora calc $ ne% Calculadora(); int resultado $ calc.somar(2, &); assertEquals(', resultado); } }

Se o m0todo passar no testeCCC

Se o m0todo n(o passar no testeCCC

&utros Asserts
"oid assert()uals(*bject e+pected, *bject actual) "oid assert rue(boolean condition) "oid assert,alse(boolean condition) "oid -ail() "oid assertArra.()uals(*bject/0 e+pecteds, *bject/0 actuals) "oid assert1ull(*bject object) "oid assert1ot1ull(*bject object) "oid assert()uals(#tring message, *bject e+pected, *bject actual)

Aoas 6r.ticas

Cada classe do sistema deve ter sua pr#pria classe testadora Cada m0todo do sistema deve ter seu pr#prio m0todo testador & nome das classes testadoras devem seguir o padr(o Test8omeClasseTestada

8(o pre,udica o code completion Classes recon1ecidas automaticamente pelo Maven

Aoas 6r.ticas

6acote da classe testadora deve ser o mesmo da classe testada

6ermite o teste de m0todos protected

Classes testadoras devem ser arma/enadas em pastas separadas


*acilita o empacotamento da aplica'(o src>test>,ava

6adr(o do Maven

Classe Usuario
public class 2suario { pri"ate #tring nome; pri"ate 3nteger idade; 44get e set... }

:alida'(o de um Usu.rio
public boolean "alidar2suario(2suario usr) { i- (usr.get3dade() 5 6 77 usr.get1ome().lengt8() 5 2) { return true; } return -alse; }

Testando a :alida'(o
! est public "oid test9alidar2suario() { 2suario usuario $ ne% 2suario(); usuario.set3dade(1:); usuario.set1ome(;Cejug;); boolean resultado $ ne% 2suario<anager()."alidar2suario(usuario); assertTrue(resultado); }

Testando a :alida'(o
! est public "oid test9alidar3n"alido() { 2suario usuario $ ne% 2suario(); usuario.set3dade(1:); usuario.set1ome(;;); boolean resultado $ ne% 2suario<anager()."alidar2suario(usuario); assertFalse(resultado); }

)solando os M0todos Testados

A maioria dos m0todos de um sistema possui dependDncias e%ternas E classe Umas das principais caracter+sticas dos testes de unidade 0 o isolamento das unidades testadas

6ermite acilmente identi icar o local do erro

Diminui o tempo de debug

As dependDncias n(o precisam estar prontas para $ue o m0todo se,a testado

6ara isolar os m0todos testados3 as dependDncias devem ser substitu+das por dependDncias 4 alsas5

M0todo com DependDncia


public "oid inserir2suario(2suario usuario) { usuario.set=ataCadastro(ne% =ate()); i-("alidar2suario(usuario)){ usuario=A*.inserir2suario(usuario); } else { t8ro% ne% 3llegalArgument(+ception(); } }

&b,etos Mock

8a reali/a'(o dos testes <em tempo de e%ecu'(o=3 as dependDncias s(o substitu+das por ob,etos Mock

)n,e'(o de dependDncia

Simulam as dependDncias dos m0todos testados S(o ob,etos 4va/ios5

8(o cont0m nen1uma l#gica

6odem ser eitos pelo pr#prio desenvolvedor ou a partir de alguma biblioteca

EasyMock

Aiblioteca para gera'(o din2mica de Mocks Gera ob,etos mock $ue implementam $ual$uer inter ace da aplica'(o

6ossui uma e%tens(o para gera'(o de mocks para classes

EasyMock

6ermite veri icar se o m0todo testado colaborou corretamente com a dependDncia

6ermite a con igura'(o dos ob,etos mock

?uais os argumentos $ue o mock deve receber do m0todo testado ?ual deve ser o retorno do m0todo c1amado Se a c1amada deve lan'ar alguma e%ce'(o

*acilidade para simular condi'-es de erro

Utili/ando Mocks
FCCriar o mock da inter ace a ser simulada GCCon igurar o comportamento do mock HC*a/er com $ue a unidade testada utili/e o ob,eto mock ao inv0s da dependDncia original
FC)n,etar o Mock

ICC1amar a unidade a ser testada JC:eri icar o valor retornado KC:eri icar se a unidade testada colaborou corretamente com o mock

Utili/ando Mocks
44 1. criando o moc> 2suario=A* moc> $ (as.<oc>.createMock(2suario=A*.class);

Utili/ando Mocks
44 2. con-igurando o comportamento do 44 moc> 2suario usuario $ ne% 2suario(); usuario.set3dade(2'); usuario.set1ome(;Ca-? com apioca;); moc>.inserir2suario(usuario); (as.<oc>.replay(moc>);

Utili/ando Mocks
44 &. 3njetando o <oc> 2suario<anager manager $ ne% 2suario<anager(); manager.set2suario=A*(moc>); 44 @. c8amando o m?todo a ser 44 testado manager.inserir2suario(usuario);

Utili/ando Mocks
44 '. 9eri-icando o comportamento do 44 m?todo assertNotNull(usuario.get=ataCadastro()); 44 A. 9eri-icando se o m?todo 44 usuario=ao.inserir() -oi c8amado com o 44 usuBrio passado (as.<oc>.verify(moc>);

Mocks L Aoas 6r.ticas

Sempre utili/e in,e'(o de dependDncias em suas classes Acesse as dependDncias atrav0s de suas )nter aces e n(o atrav0s da implementa'(o Ten1a bem de inido $ual o comportamento de seus m0todos nas intera'-es com as dependDncias

Testando a Camada de 6ersistDncia

Como ter certe/a de $ue seu c#digo de acesso a dados est. lendo e escrevendo corretamente na base de dados7 " necess.ria uma integra'(o com o banco de dados na reali/a'(o dos testes

Misto entre teste de unidade e teste de integra'(o

?uando eita de orma n(o autom.tica3 a veri ica'(o depende da inspe'(o visual do conte9do da base de dados

Testando a Camada de 6ersistDncia

6ara automati/ar os testes duas condi'-es tem $ue ser satis eitas

& conte9do da base de dados tem ser con1ecido no in+cio de cada teste Deve ser poss+vel veri icar o conte9do da base de dados ap#s cada teste

&s testes ainda devem ser reali/ados independentemente

Testar a inser'(o independentemente da sele'(o

DbUnit

E%tens(o do Junit especiali/ada em testes integrados ao banco de dados 6ermite o controle do conte9do arma/enado na base de dados

E%porta dados para a base atrav0s de ar$uivos MMN

6ossui m0todos de veri ica'(o do estado da base de dados

)mporta dados da base e compara com ar$uivos MMN

Testando com o DbUnit

& conte9do da base de dados 0 con igurado atrav0s de DataSet no ormato MMN 6or de ault3 antes de cada teste a base de dados 0 esva/iada e re-populada com o conte9do do DataSet

Cdataset5 C2suario codigo$;D1; nome$;jose-ino; idade$;26; 45 C2suario codigo$;D2; nome$;maria; idade$;@6; 45 C2suario codigo$;D&; nome$;jose; idade$;@6; 45 C4dataset5

Testando com o DbUnit


Classe de teste deve 1erdar de DatabaseTestCase )mplementar os m0todos

)DatabaseConnection getConnection<=

;etorna uma cone%(o com a base de dados ;etorna o DataSet para o povoamento da base de dados

)DataSet getDataSet<=

Testando com o DbUnit


protected 3=atabaseConnection getConnection() t8ro%s Class1ot,ound(+ception, #EF(+ception { Class.forName(;org.8s)ldb.jdbc=ri"er;); Connection jdbcConnection $ =ri"er<anager.getConnection( ;jdbcG8s)ldbGsample;, ;sa;, ;;); return ne% =atabaseConnection(jdbcConnection); }

Testando com o DbUnit


protected 3=ata#et get=ata#et() t8ro%s =ata#et(+ception, 3*(+ception { ,ile3nput#tream -ile3# $ ne% ,ile3nput#tream(;dataset.+ml;); return ne% ,latHml=ata#et(-ile3#); }

Testando a Sele'(o de Usu.rios


public inter-ace 2suario=A* { FistC2suario5 selecionar2suarios( #tring nome); }

;eali/ando o Teste

Montar o<s= par2metro<s= para a busca Criar o retorno esperado de acordo com o DataSet de povoamento da base de dados ;eali/ar a busca :eri icar se o resultado da busca 0 igual ao resultado esperado

! est public "oid test#elecionar2suarios() { #tring parametroIusca $ ;jose;; FistC2suario5 esperado $ ne% Arra.FistC2suario5(); esperado.add(ne% 2suario(D&F)); esperado.add(ne% 2suario(D1F)); FistC2suario5 retorno usuario=A*. selecionar2suarios(parametroIusca); } assertEquals(esperado, retorno);

Desenvolvimento Guiado por Testes <TDD=


A escrita de testes a,uda na mel1oria do design do c#digo Ao se perceber os bene +cios dos testes3 a tendDncia 0 escreve-los o $uanto antes Com o alcance da maturidade3 durante a implementa'(o de um m0todo o desenvolvedor ,. imagina como ir. testa-lo

TDD

?uanto mais cedo os testes s(o implementados3 maiores s(o os bene +cios

Evita $ue bugs se espal1em pela aplica'(o e os tornam mais .ceis de ser corrigidos

&s adeptos do TDD levam essa pr.tica ao estremo

&s testes s(o escritos antes do c#digo a ser testado

TDD

A regra b.sica do TDD 0 somente escrever c#digo se e%istir algum teste al1ando

;egra v.lida para implementa'(o de novas uncionalidades ou para corre'(o de bugs

Somente o c#digo estritamente necess.rio para a/er o teste passar deve ser escrito

;e atora'-es s(o permitidas

Codi icando com TDD

Escreva o teste para a uncionalidade dese,ada

& teste ir. al1ar

Escreva o c#digo necess.rio e su iciente para o teste passar ;e atore o c#digo

Elimine poss+veis duplica'-es de c#digo

;epita os passos $uantas ve/es necess.rio Entregue o c#digo

:antagens do TDD

Antes mesmo de come'ar a implementar o m0todo3 o desenvolvedor ,. tem de inido $ual ser. seu comportamento & c#digo ,. nasce sem v+cios de design Evita $ue bugs se,am adicionados ao c#digo

:antagens do TDD

Mant0m o desenvolvedor ocado no problema a ser resolvido

C#digo 0 o mais simples $ue unciona

8(o procura antecipar mudan'as

Manuten'(o 0 garantida pela n(o duplicidade e pela simplicidade do c#digo

Duvidas777

Contato

abricioClemosOgmailCcom discussaoOce,ugCdevC,avaCnet

;e erDncias

1ttpB>>!!!C,unitCorg> 1ttpB>>!!!CeasymockCorg> 1ttpB>>dbunitCsource orgeCnet> JUnit in Action

:incent Massol

JUnit ;ecipesB 6ractical Met1ods or 6rogrammer Testing

JC AC ;ainsberger :inicius Man1aes Teles

E%treme 6rogramming

You might also like