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

Testes de unidade na prática

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Testes de unidade na prática

Por que usá-los? Como são escritos? Como automatizá-los? Serão abordados aspectos conceituais de qualidade de código, cobertura de testes e TDD, com exemplos em aplicações desenvolvidas na Meritt.

Avatar for Tiago Furtado

Tiago Furtado

October 14, 2014
Tweet

Other Decks in Programming

Transcript

  1. Testes de unidade na prática Por quê? Quando? Como? Tiago

    Furtado <[email protected]> Full-stack developer, Meritt XVII SECCOM
  2. Testes de unidade i n t e r f a

    c e C a l c u l a t o r I n t e r f a c e { p u b l i c f u n c t i o n s u m ( $ f i r s t , $ s e c o n d ) ; p u b l i c f u n c t i o n s u b t r a c t ( $ f i r s t , $ s e c o n d ) ; } c l a s s C a l c u l a t o r i m p l e m e n t s C a l c u l a t o r I n t e r f a c e { / * . . . * / } c l a s s C a l c u l a t o r T e s t { / * * @ t e s t * / p u b l i c f u n c t i o n s u m S h o u l d R e t u r n T h e S u m O f T w o N u m b e r s ( ) { $ c a l c u l a t o r = n e w C a l c u l a t o r ( ) ; $ r e s u l t = $ c a l c u l a t o r - > s u m ( 1 , 2 ) ; i f ( $ r e s u l t ! = = 3 ) { t h r o w n e w E x c e p t i o n ( " S o m e t h i n g w r o n g ' s n o t r i g h t ¯ \ _ ( ツ) _ / ¯ " ) ; } } } P H P 13/70
  3. Testes de unidade Por quê? Software livre de defeitos deveria

    ser sempre entregue Mas... · · software é muito complexo pessoas são imperfeitas! ><" - - 14/70
  4. O todo é maior do que a simples soma das

    suas partes. “ ” Aristóteles
  5. Testes de unidade Por quê? Garantir a correção das partes

    i n t e r f a c e P e r s o n I n t e r f a c e { p u b l i c f u n c t i o n c a n B e A r r e s t e d ( ) ; } c l a s s P e r s o n i m p l e m e n t s P e r s o n I n t e r f a c e { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ a g e ) ; / * . . . * / } ( n e w P e r s o n ( 1 7 ) ) - > c a n B e A r r e s t e d ( ) ; ( n e w P e r s o n ( 1 8 ) ) - > c a n B e A r r e s t e d ( ) ; ( n e w P e r s o n ( 1 9 ) ) - > c a n B e A r r e s t e d ( ) ; ( n e w P e r s o n ( - 1 ) ) - > c a n B e A r r e s t e d ( ) ; ( n e w P e r s o n ( 0 ) ) - > c a n B e A r r e s t e d ( ) ; ( n e w P e r s o n ( " R U K M ? " ) ) - > c a n B e A r r e s t e d ( ) ; P H P
  6. Testes de unidade Por quê? Ampliar a capacidade de análise

    do todo i n t e r f a c e P e r s o n I n t e r f a c e { / * . . . * / } c l a s s P e r s o n i m p l e m e n t s P e r s o n I n t e r f a c e { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ a g e ) ; / * . . . * / } i n t e r f a c e P o l i c e I n t e r f a c e { p u b l i c f u n c t i o n a r r e s t ( P e r s o n I n t e r f a c e $ p e r s o n ) ; } c l a s s P o l i c e i m p l e m e n t s P o l i c e I n t e r f a c e { / * . . . * / } $ p o l i c e = n e w P o l i c e ( ) ; $ p o l i c e - > a r r e s t ( n e w P e r s o n ( 1 5 ) ) ; $ p o l i c e - > a r r e s t ( n e w P e r s o n ( 1 9 ) ) ; P H P
  7. Testes de unidade Como? Manualmente f u n c t

    i o n s u m ( $ a , $ b ) { r e t u r n $ a + 0 ; } p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 0 , 0 , s u m ( 0 , 0 ) , 0 ) ; p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 1 , 0 , s u m ( 1 , 0 ) , 1 ) ; p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 0 , 1 , s u m ( 0 , 1 ) , 1 ) ; P H P s u m ( 0 , 0 ) = 0 [ 0 ] s u m ( 1 , 0 ) = 1 [ 1 ] s u m ( 0 , 1 ) = 0 [ 1 ] 18/70
  8. Testes de unidade Como? Manualmente f u n c t

    i o n s u m ( $ a , $ b ) { r e t u r n $ a + $ b ; } p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 0 , 0 , s u m ( 0 , 0 ) , 0 ) ; p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 1 , 0 , s u m ( 1 , 0 ) , 1 ) ; p r i n t f ( " s u m ( % d , % d ) = % d [ % d ] \ n " , 0 , 1 , s u m ( 0 , 1 ) , 1 ) ; P H P s u m ( 0 , 0 ) = 0 [ 0 ] s u m ( 1 , 0 ) = 1 [ 1 ] s u m ( 0 , 1 ) = 1 [ 1 ] 19/70
  9. Testes de unidade 1 < ? p h p 2

    f u n c t i o n s u m ( $ a , $ b ) { 3 r e t u r n 0 + $ b ; 4 } 5 6 f u n c t i o n s u m T e s t ( $ a , $ b , $ c ) { 7 i f ( s u m ( $ a , $ b ) = = = $ c ) { r e t u r n ; } 8 t h r o w n e w E x c e p t i o n ( / * . . . * / ) ; 9 } 1 0 s u m T e s t ( 0 , 0 , 0 ) ; 1 1 s u m T e s t ( 1 , 0 , 1 ) ; 1 2 s u m T e s t ( 0 , 1 , 1 ) ; P H P P H P F a t a l e r r o r : U n c a u g h t e x c e p t i o n ' E x c e p t i o n ' i n s u m T e s t . p h p : 8 S t a c k t r a c e : # 0 s u m T e s t . p h p ( 1 1 ) : s u m T e s t ( 1 , 0 , 1 ) # 1 { m a i n } t h r o w n i n s u m T e s t . p h p o n l i n e 8
  10. Testes de unidade Como? Usando um framework de testes c

    l a s s C a l c u l a t o r { p u b l i c f u n c t i o n s u m ( $ a , $ b ) { r e t u r n $ a + $ b ; } } c l a s s C a l c u l a t o r T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * @ t e s t * / p u b l i c f u n c t i o n s u m T e s t ( ) { $ t h i s - > a s s e r t S a m e ( 0 , s u m ( 0 , 0 ) ) ; $ t h i s - > a s s e r t S a m e ( 1 , s u m ( 1 , 0 ) ) ; $ t h i s - > a s s e r t S a m e ( 1 , s u m ( 0 , 1 ) ) ; } } P H P
  11. Testes de unidade c l a s s P o

    l i c e i m p l e m e n t s P o l i c e I n t e r f a c e { p u b l i c f u n c t i o n a r r e s t ( P e r s o n I n t e r f a c e $ p e r s o n ) { i f ( ! $ p e r s o n - > c a n B e A r r e s t e d ( ) ) { t h r o w n e w E x c e p t i o n ( / * . . . * / ) ; } } } P H P 28/70
  12. Testes de unidade c l a s s P o

    l i c e T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * @ t e s t * / p u b l i c f u n c t i o n a r r e s t S h o u l d T h r o w E x c e p t i o n I f P e r s o n C a n t B e A r r e s t e d ( ) { $ p e r s o n = $ t h i s - > g e t M o c k F o r A b s t r a c t C l a s s ( P e r s o n I n t e r f a c e : : c l a s s ) ; $ p e r s o n - > e x p e c t s ( $ t h i s - > o n c e ( ) ) - > m e t h o d ( ' c a n B e A r r e s t e d ' ) - > w i l l R e t u r n ( f a l s e ) ; $ t h i s - > s e t E x p e c t e d E x c e p t i o n ( E x c e p t i o n : : c l a s s ) ; $ p o l i c e = n e w P o l i c e ( ) ; $ p o l i c e - > a r r e s t ( $ p e r s o n ) ; } } P H P 29/70
  13. Test-driven development (TDD) 1. Escrever um teste c l a

    s s C a l c u l a t o r T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * * @ t e s t * / p u b l i c f u n c t i o n s u m T e s t ( ) { } } P H P 35/70
  14. Test-driven development (TDD) 2. Garantir que o novo teste falha

    $ . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 7 5 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 0 a s s e r t i o n s ) 36/70
  15. Test-driven development (TDD) 2. Garantir que o novo teste falha

    c l a s s C a l c u l a t o r T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * * @ t e s t * / p u b l i c f u n c t i o n s u m T e s t ( ) { $ c a l c u l a t o r = n e w C a l c u l a t o r ( ) ; } } P H P 37/70
  16. Test-driven development (TDD) 2. Garantir que o novo teste falha

    $ . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . P H P F a t a l e r r o r : C l a s s ' T F u r t a d o \ U n i t T e s t S a m p l e \ C a l c u l a t o r ' n o t f o u n d i n . . . / t e s t / C a l c u l a t o r T e s t . p h p o n l i n e 1 9 P H P S t a c k t r a c e : P H P 1 . { m a i n } ( ) . / v e n d o r / p h p u n i t / p h p u n i t / p h p u n i t : 0 . . . 38/70
  17. Test-driven development (TDD) 3. Escrever código c l a s

    s C a l c u l a t o r { } P H P 40/70
  18. Test-driven development (TDD) 4. Garantir que os testes passam $

    . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 6 5 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 0 a s s e r t i o n s ) 41/70
  19. Test-driven development (TDD) 1. Escrever um teste c l a

    s s C a l c u l a t o r T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * * @ t e s t * / p u b l i c f u n c t i o n s u m T e s t ( ) { $ c a l c u l a t o r = n e w C a l c u l a t o r ( ) ; $ t h i s - > a s s e r t S a m e ( 3 , $ c a l c u l a t o r - > s u m ( 1 , 2 ) ) ; } } P H P 44/70
  20. Test-driven development (TDD) 2. Garantir que o novo teste falha

    $ . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . P H P F a t a l e r r o r : C a l l t o u n d e f i n e d m e t h o d T F u r t a d o \ U n i t T e s t S a m p l e \ C a l c u l a t o r : : s u m ( ) i n . . . / t e s t / C a l c u l a t o r T e s t . p h p o n l i n e 2 0 P H P S t a c k t r a c e : P H P 1 . { m a i n } ( ) . / v e n d o r / p h p u n i t / p h p u n i t / p h p u n i t : 0 . . . 45/70
  21. Test-driven development (TDD) 3. Escrever código c l a s

    s C a l c u l a t o r { p u b l i c f u n c t i o n s u m ( $ a , $ b ) { $ s u m = 3 ; r e t u r n $ s u m ; } } P H P 46/70
  22. Test-driven development (TDD) 4. Garantir que os testes passam $

    . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 7 7 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 1 a s s e r t i o n ) 47/70
  23. Test-driven development (TDD) 5. Refatorar o código c l a

    s s C a l c u l a t o r { p u b l i c f u n c t i o n s u m ( $ a , $ b ) { r e t u r n 3 ; } } $ s u m = 3 ; r e t u r n $ s u m ; P H P 48/70
  24. Test-driven development (TDD) 5. Refatorar o código $ . /

    v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 8 7 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 1 a s s e r t i o n ) 49/70
  25. Test-driven development (TDD) 1. Escrever um teste c l a

    s s C a l c u l a t o r T e s t e x t e n d s P H P U n i t _ F r a m e w o r k _ T e s t C a s e { / * * * @ t e s t * / p u b l i c f u n c t i o n s u m T e s t ( ) { $ c a l c u l a t o r = n e w C a l c u l a t o r ( ) ; $ t h i s - > a s s e r t S a m e ( 3 , $ c a l c u l a t o r - > s u m ( 1 , 2 ) ) ; $ t h i s - > a s s e r t S a m e ( 4 , $ c a l c u l a t o r - > s u m ( 2 , 2 ) ) ; } } P H P 51/70
  26. Test-driven development (TDD) 2. Garantir que o novo teste falha

    $ . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . F T i m e : 7 6 m s , M e m o r y : 3 . 0 0 M b T h e r e w a s 1 f a i l u r e : 1 ) T F u r t a d o \ U n i t T e s t S a m p l e \ C a l c u l a t o r T e s t : : s u m T e s t F a i l e d a s s e r t i n g t h a t 3 i s i d e n t i c a l t o 4 . . . . / t e s t / C a l c u l a t o r T e s t . p h p : 2 1 F A I L U R E S ! T e s t s : 1 , A s s e r t i o n s : 2 , F a i l u r e s : 1 . 52/70
  27. Test-driven development (TDD) 3. Escrever código c l a s

    s C a l c u l a t o r { p u b l i c f u n c t i o n s u m ( $ a , $ b ) { $ s u m = $ a + $ b ; r e t u r n $ s u m ; } } r e t u r n 3 ; P H P 53/70
  28. Test-driven development (TDD) 4. Garantir que os testes passam $

    . / v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 9 0 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 2 a s s e r t i o n s ) 54/70
  29. Test-driven development (TDD) 5. Refatorar o código c l a

    s s C a l c u l a t o r { p u b l i c f u n c t i o n s u m ( $ a , $ b ) { ; r e t u r n $ a + $ b ; } } $ s u m = $ a + $ b ; r e t u r n $ s u m P H P 55/70
  30. Test-driven development (TDD) 5. Refatorar o código $ . /

    v e n d o r / b i n / p h p u n i t - - b o o t s t r a p . / v e n d o r / a u t o l o a d . p h p t e s t / C a l c u l a t o r T e s t . p h p P H P U n i t 4 . 5 - g f 7 5 e 6 b 2 b y S e b a s t i a n B e r g m a n n . . T i m e : 8 7 m s , M e m o r y : 2 . 7 5 M b O K ( 1 t e s t , 1 a s s e r t i o n ) 56/70
  31. Quanto do software deve estar coberto por testes de unidade?

    100%! TODO! O software INTEIRO! Deu pra endenter, né? 59/70
  32. Considerações finais Testes de unidade são... ... essenciais para garantir

    a manutenibilidade do software ... instrumentos de simples implementação ... muito valiosos para criar um produto de qualidade ... uma importante forma de documentação técnica ... divertidos! Por que não? · · · · · 66/70
  33. Considerações finais Testes de unidade não são... ... a abordagem

    definitiva para testes de software ... uma garantia de qualidade do produto final ... a solução mágica para software mal arquitetado · · · 67/70
  34. Pay attention to zeros. If there is a zero, someone

    will divide by it. “ ” Cem Kaner