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

JUnit: beyond the basics

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for Adam Dudczak Adam Dudczak
February 10, 2015
31

JUnit: beyond the basics

Avatar for Adam Dudczak

Adam Dudczak

February 10, 2015

Transcript

  1. WHO AM I? Software Engineer in Allegro group Working with

    Java (and JUnit) since 2004 One of the leaders of Co-organizer of conference Poznań JUG GeeCON
  2. ERRORRATE CLASS p u b l i c c l

    a s s E r r o r R a t e { d o u b l e e r r o r R a t e ; p u b l i c E r r o r R a t e ( l o n g n o O f I t e m s , l o n g n o O f E r r o r s ) { e r r o r R a t e = c a l c u l a t e E r r o r R a t e ( n o O f I t e m s , n o O f E r r o r s ) ; } d o u b l e c a l c u l a t e E r r o r R a t e ( l o n g n o O f I t e m s , l o n g n o O f E r r o r s ) { . . . } p u b l i c S t r i n g g e t E r r o r R a t e A s S t r i n g ( ) { r e t u r n S t r i n g . f o r m a t ( " % 2 . 0 2 f " , e r r o r R a t e ) ; } }
  3. SIMPLE ERRORRATE TEST p u b l i c c

    l a s s E r r o r R a t e T e s t { @ T e s t p u b l i c v o i d s h o u l d C a l c u l a t e E r r o r R a t e ( ) { / / g i v e n E r r o r R a t e e r r o r R a t e = n e w E r r o r R a t e ( 1 0 0 , 1 0 ) ; / / w h e n S t r i n g r e s u l t = e r r o r R a t e . g e t E r r o r R a t e A s S t r i n g ( ) ; / / t h e n a s s e r t T h a t ( r e s u l t , i s ( " 0 . 0 1 " ) ) ; } }
  4. SIMPLE ERRORRATE TEST O b j e c t [

    ] [ ] t e s t P a r a m e t e r s = n e w O b j e c t [ ] [ ] { n e w O b j e c t [ ] { 1 0 0 , 1 , " 0 . 0 1 " } , n e w O b j e c t [ ] { 0 , 0 , " 0 . 0 0 " } , } ; @ T e s t p u b l i c v o i d s h o u l d C a l c u l a t e E r r o r R a t e 1 ( ) { f o r ( i n t i = 0 ; i > t e s t P a r a m e t e r s . l e n g t h ; i + + ) { E r r o r R a t e e r r o r R a t e = n e w E r r o r R a t e ( ( I n t e g e r ) t e s t P a r a m e t e r s [ i ] [ 0 ] , ( I n t e g e r ) t e s t P a r a m e t e r s [ i ] [ 1 ] ) ; S t r i n g r e s u l t = e r r o r R a t e . g e t E r r o r R a t e A s S t r i n g ( ) ; a s s e r t T h a t ( r e s u l t , i s ( ( S t r i n g ) t e s t P a r a m e t e r s [ i ] [ 2 ] ) ) ; } }
  5. LET'S BRAKE SOMETHING... O b j e c t [

    ] [ ] t e s t P a r a m e t e r s = n e w O b j e c t [ ] [ ] { n e w O b j e c t [ ] { 1 0 0 , 1 , " 0 . 0 2 " } , n e w O b j e c t [ ] { 0 , 0 , " 0 . 0 2 " } , } ; First error stops test All cases are seen as one test
  6. JUNIT PARAMETRIZED @ R u n W i t h

    ( P a r a m e t e r i z e d . c l a s s ) p u b l i c c l a s s E r r o r R a t e T e s t { @ P a r a m e t e r s p u b l i c s t a t i c C o l l e c t i o n < O b j e c t [ ] > d a t a ( ) { r e t u r n A r r a y s . a s L i s t ( n e w O b j e c t [ ] [ ] { n e w O b j e c t [ ] { 1 0 0 , 1 , " 0 . 0 1 " } , n e w O b j e c t [ ] { 0 , 0 , " 0 . 0 0 " } , } ) ; } . . .
  7. JUNIT PARAMETRIZED (2) . . . l o n g

    t o t a l N u m b e r O f I t e m s ; l o n g t o t a l N u m b e r O f R e j e c t e d ; d o u b l e f i n a l E r r o r R a t e ; p u b l i c E r r o r R a t e T e s t ( l o n g t o t a l N u m b e r O f I t e m s , l o n g t o t a l N u m b e r O f R e j e c t e d , d o u b l e f i n a l E r r o r R a t e ) { t h i s . t o t a l N u m b e r O f I t e m s = t o t a l N u m b e r O f I t e m s ; t h i s . t o t a l N u m b e r O f R e j e c t e d = t o t a l N u m b e r O f R e j e c t e d ; t h i s . f i n a l E r r o r R a t e = f i n a l E r r o r R a t e ; } . . .
  8. JUNIT PARAMETRIZED (3) . . . @ T e s

    t p u b l i c v o i d s h o u l d C a l c u l a t e E r r o r R a t e ( ) { / / g i v e n E r r o r R a t e e r r o r R a t e = n e w E r r o r R a t e ( t o t a l N u m b e r O f I t e m s , t o t a l N u m b e r O f R e j e c t e d ) ; / / w h e n S t r i n g r e s u l t = e r r o r R a t e . g e t E r r o r R a t e A s S t r i n g ( ) ; / / t h e n a s s e r t T h a t ( r e s u l t , i s ( f i n a l E r r o r R a t e ) ) ; } . . .
  9. LET'S BRAKE SOMETHING... Two independent tests A lot of boilerplate

    code! Only one occurance of @Parameters per class
  10. JUNIT-PARAMS Parameterised tests that don't suck Created by Paweł Lipiński

    A lot of very interesting ideas. https://code.google.com/p/junitparams/ < d e p e n d e n c y > < g r o u p I d > p l . p r a g m a t i s t s < / g r o u p I d > < a r t i f a c t I d > J U n i t P a r a m s < / a r t i f a c t I d > < v e r s i o n > 1 . 0 . 2 < / v e r s i o n > < s c o p e > t e s t < / s c o p e > < / d e p e n d e n c y >
  11. JUNIT-PARAMS - SHOWCASE @ R u n W i t

    h ( J U n i t P a r a m s R u n n e r . c l a s s ) p u b l i c c l a s s S a m p l e s _ o f _ U s a g e _ T e s t { @ T e s t @ P a r a m e t e r s ( { " A A A , 1 " , " B B B , 2 " } ) p u b l i c v o i d p a r a m s _ i n _ a n n o t a t i o n ( S t r i n g p 1 , I n t e g e r p 2 ) { } @ T e s t @ P a r a m e t e r s p u b l i c v o i d p a r a m s _ i n _ d e f a u l t _ m e t h o d ( S t r i n g p 1 , I n t e g e r p 2 ) { } p r i v a t e O b j e c t p a r a m e t e r s F o r P a r a m s _ i n _ d e f a u l t _ m e t h o d ( ) { r e t u r n $ ( $ ( " A A A " , 1 ) , $ ( " B B B " , 2 ) ) ; }
  12. JUNIT-PARAMS - SHOWCASE @ T e s t @ P

    a r a m e t e r s ( m e t h o d = " n a m e d 2 , n a m e d 3 " ) p u b l i c v o i d p a r a m s _ i n _ m u l t i p l e _ m e t h o d s ( S t r i n g p 1 , I n t e g e r p 2 ) { } p r i v a t e O b j e c t n a m e d 2 ( ) { r e t u r n $ ( $ ( " A A A " , 1 ) ) ; } p r i v a t e O b j e c t n a m e d 3 ( ) { r e t u r n $ ( $ ( " B B B " , 2 ) ) ; } @ T e s t @ P a r a m e t e r s ( s o u r c e = P a r a m e t e r s P r o v i d e r s T e s t . O n e I n t e g e r P r o v i d e r . c l a s s ) p u b l i c v o i d p a r a m e t e r s _ f r o m _ e x t e r n a l _ c l a s s ( i n t i n t e g e r ) { }
  13. JUNIT-PARAMS - SHOWCASE @ T e s t @ F

    i l e P a r a m e t e r s ( " s r c / t e s t / r e s o u r c e s / t e s t . c s v " ) p u b l i c v o i d l o a d _ p a r a m s _ f r o m _ c s v ( i n t a g e , S t r i n g n a m e ) { } @ T e s t @ F i l e P a r a m e t e r s ( v a l u e = " s r c / t e s t / r e s o u r c e s / t e s t . c s v " , m a p p e r = P e r s o n M a p p e r . c l a s s ) p u b l i c v o i d l o a d _ p a r a m s _ f r o m _ a n y _ f i l e ( P e r s o n T e s t . P e r s o n p e r s o n ) { } @ T e s t @ F i l e P a r a m e t e r s ( " c l a s s p a t h : t e s t . c s v " ) p u b l i c v o i d l o a d _ p a r a m s _ f r o m _ c l a s s p a t h ( i n t a g e , S t r i n g n a m e ) { }
  14. JUNIT-PARAMS More examples can be found at i Samples_of_Usage_Test.java PersonTest.java

    Similar to approach in TestNG Test code is clear and concise - YEAH!!
  15. ORG.JUNIT.EXPERIMENTAL.THEORIES Theory is, in fact a parameterized test This approach

    is more focused on requirements than on particular test cases Similar to ScalaCheck (Scala) / QuickCheck (Erlang)
  16. ORG.JUNIT.EXPERIMENTAL.THEORIES Theory describes features of class/method and verifies them using

    given set of input data Theory is executed as one test If assertion fails for any set of input data whole theory fails Example in ErrorRate_05_Theory_Test.java
  17. RANDOMIZED UNIT TESTING "Monkey testing" - more randomness in your

    tests http://labs.carrotsearch.com/randomizedtesting.html
  18. RANDOMIZED UNIT TESTING @ T e s t p u

    b l i c v o i d r a n d o m i z e d T e s t i n g ( ) { / / H e r e w e p i c k t w o p o s i t i v e i n t e g e r s . / / N o t e s u p e r c l a s s u t i l i t y m e t h o d s . i n t a = r a n d o m I n t B e t w e e n ( 0 , I n t e g e r . M A X _ V A L U E ) ; i n t b = r a n d o m I n t B e t w e e n ( 0 , I n t e g e r . M A X _ V A L U E ) ; i n t r e s u l t = A d d e r . a d d ( a , b ) ; a s s e r t T r u e ( r e s u l t + " < ( " + a + " o r " + b + " ) ? " , r e s u l t > = a & & r e s u l t > = b ) ; }
  19. @THREADLEAKING* Randomized Unit Testing library helps to check/control threads activity

    @ T h r e a d L e a k i n g * annotations verfies if threads are leaking from your tests/suite Check out ErrorRate_06_Randomized_Test.java
  20. @RULE Resuable @Before/@After... and more Example in JunitRulesShowcaseTest JUnit has

    several built-in @Rules, ex.: ExternalResource, ExpectedException, TestName...
  21. @RULE p u b l i c s t a

    t i c c l a s s H a s T e m p F o l d e r { @ R u l e p u b l i c T e m p o r a r y F o l d e r f o l d e r = n e w T e m p o r a r y F o l d e r ( ) ; @ T e s t p u b l i c v o i d t e s t U s i n g T e m p F o l d e r ( ) t h r o w s I O E x c e p t i o n { F i l e c r e a t e d F i l e = f o l d e r . n e w F i l e ( " m y f i l e . t x t " ) ; F i l e c r e a t e d F o l d e r = f o l d e r . n e w F o l d e r ( " s u b f o l d e r " ) ; / / . . . } } @Rule cannot be applied to static fields - use @ClassRule
  22. @RULE IN BETAMAX i m p o r t c

    o . f r e e s i d e . b e t a m a x . B e t a m a x ; i m p o r t c o . f r e e s i d e . b e t a m a x . R e c o r d e r ; i m p o r t o r g . j u n i t . * ; p u b l i c c l a s s M y T e s t { @ R u l e p u b l i c R e c o r d e r r e c o r d e r = n e w R e c o r d e r ( ) ; @ B e t a m a x ( t a p e = " m y t a p e " ) @ T e s t p u b l i c v o i d t e s t M e t h o d T h a t A c c e s s e s E x t e r n a l W e b S e r v i c e ( ) { } }
  23. @RULE WITH SPRING AND WIREMOCK @ R u l e

    p u b l i c W i r e M o c k R u l e w i r e M o c k R u l e = n e w W i r e M o c k R u l e ( 8 0 8 9 ) ; / / C h e c k o u t h t t p : / / w i r e m o c k . o r g / @ R u l e p u b l i c T e s t R u l e c o n t e x t R u l e = n e w S p r i n g C o n t e x t R u l e ( n e w S t r i n g [ ] { " t e s t C o n t e x t . x m l " } , t h i s ) ; @ A u t o w i r e d p u b l i c S t r i n g b a r ; @ T e s t p u b l i c v o i d t e s t B a r ( ) t h r o w s E x c e p t i o n { . . . . }
  24. JUNIT BENCHMARKS AND TIMEOUT p u b l i c

    c l a s s M y T e s t { @ R u l e p u b l i c T e s t R u l e b e n c h m a r k R u n = n e w B e n c h m a r k R u l e ( ) ; @ R u l e p u b l i c T e s t T i m e o u t t i m e o u t R u l e = n e w T e s t T i m e o u t ( 3 0 ) ; @ T e s t p u b l i c v o i d t w e n t y M i l l i s ( ) t h r o w s E x c e p t i o n { T h r e a d . s l e e p ( 2 0 ) ; } } M y T e s t . t w e n t y M i l l i s : [ m e a s u r e d 1 0 o u t o f 1 5 r o u n d s ] r o u n d : 0 . 0 2 [ + - 0 . 0 0 ] , r o u n d . g c : 0 . 0 0 [ + - 0 . 0 0 ] , G C . c a l l s : 0 , G C . t i m e : 0 . 0 0 , t i m e . t o t a l : 0 . 3 2 , t i m e . w a r m u p : 0 . 1 2 , t i m e . b e n c h : 0 . 2 0
  25. BETTER EXCEPTION HANDLING Example by Rafał Borowiec ( ) blog.codeleak.pl/

    p u b l i c c l a s s E x p e c t e d E x c e p t i o n s T e s t { @ R u l e p u b l i c E x p e c t e d E x c e p t i o n t h r o w n = E x p e c t e d E x c e p t i o n . n o n e ( ) ; @ T e s t p u b l i c v o i d v e r i f i e s T y p e A n d M e s s a g e ( ) { t h r o w n . e x p e c t ( R u n t i m e E x c e p t i o n . c l a s s ) ; t h r o w n . e x p e c t M e s s a g e ( " R u n t i m e e x c e p t i o n o c c u r r e d " ) ; t h r o w n e w R u n t i m e E x c e p t i o n ( " R u n t i m e e x c e p t i o n o c c u r r e d " ) ; } }
  26. "NEW" ASSERTIONS assertThat and built-in Hamcrest matchers Readable assertions and

    better error handling a s s e r t T h a t ( " t h i s s t r i n g " , i s ( " t h i s s t r i n g " ) ) ; a s s e r t T h a t ( t h e B i s c u i t , i s ( e q u a l T o ( m y B i s c u i t ) ) ) ; a s s e r t T h a t ( " t h i s s t r i n g " , c o n t a i n s S t r i n g ( " i s " ) ) ;
  27. ALTERNATIVE APPROACH - FEST/ASSERTJ Alternative (but in fact a mainstream)

    way of building assertions gives access to hundreds of assertions AssertJ a s s e r t T h a t ( f r o d o . g e t N a m e ( ) ) . i s E q u a l T o ( " F r o d o " ) ; a s s e r t T h a t ( f r o d o ) . i s N o t E q u a l T o ( s a u r o n ) . i s I n ( f e l l o w s h i p O f T h e R i n g ) ; a s s e r t T h a t ( s a u r o n ) . i s N o t I n ( f e l l o w s h i p O f T h e R i n g ) ;
  28. ORGANIZE TESTS IN @SUITE @ R u n W i

    t h ( S u i t e . c l a s s ) @ S u i t e C l a s s e s ( { E r r o r R a t e _ 0 1 _ S i m p l e T e s t . c l a s s , E r r o r R a t e _ 0 3 _ P a r a m e t r i z e d _ T e s t . c l a s s } ) p u b l i c c l a s s S u i t e I n i t i a l i z a t i o n E x a m p l e { @ C l a s s R u l e p u b l i c s t a t i c E x t e r n a l R e s o u r c e r e s o u r c e = n e w E x t e r n a l R e s o u r c e ( ) { @ O v e r r i d e p r o t e c t e d v o i d b e f o r e ( ) t h r o w s T h r o w a b l e { S y s t e m . o u t . p r i n t l n ( " S t a r t i n g t h e h e a v y w e i g h t S e r v e r " ) ; } ; @ O v e r r i d e p r o t e c t e d v o i d a f t e r ( ) { S y s t e m . o u t . p r i n t l n ( " S t o p p i n g t h e h e a v y w e i g h t S e r v e r " ) ; } ; } ; }
  29. CATEGORIES/SUITES AND BUILD TOOLS Suite is a bit Ant-ish -

    use Categories Categories are supported by both and Maven Gradle < b u i l d > < p l u g i n s > < p l u g i n > < a r t i f a c t I d > m a v e n - s u r e f i r e - p l u g i n < / a r t i f a c t I d > < c o n f i g u r a t i o n > < g r o u p s > c o m . e x . F a s t T e s t s , c o m . e x . R e g r e s s i o n T e s t s < / g r o u p s > < / c o n f i g u r a t i o n > < / p l u g i n > < / p l u g i n s > < / b u i l d >
  30. USE CATEGORIES ON THE @SUITE LEVEL p u b l

    i c c l a s s H e a v y I n t e g r a t i o n T e s t { @ T e s t @ C a t e g o r y ( H e a v y W e i g h t . c l a s s ) p u b l i c v o i d s h o u l d C a l c u l a t e E r r o r R a t e ( ) { a s s u m e T r u e ( i s H e a v y W e i g h t S e r v e r R u n n i n g ( ) ) ; / / h e a v e s t u f f w i t h h e a v y W e i g h t s e r v e r h e r e } . . .
  31. USE CATEGORIES ON THE @SUITE LEVEL @ R u n

    W i t h ( C a t e g o r i e s . c l a s s ) @ I n c l u d e C a t e g o r y ( H e a v y W e i g h t . c l a s s ) @ S u i t e C l a s s e s ( { E r r o r R a t e _ 0 1 _ S i m p l e T e s t . c l a s s , H e a v y I n t e g r a t i o n T e s t . c l a s s } ) p u b l i c c l a s s S u i t e W i t h C a t e g o r i e s { / / c a t e g o r y m a r k e r i n t e r f a c e p u b l i c i n t e r f a c e H e a v y W e i g h t { } . . .