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

Writing Cleaner, Sturdier Code With Unit Testing

Writing Cleaner, Sturdier Code With Unit Testing

Presentation source: https://dlh01.github.io/wcto2014

2f574b120b5dd2d8616634374cc1a4f7?s=128

David Herrera

November 16, 2014
Tweet

Transcript

  1. WRITING CLEANER, STURDIER CODE WITH UNIT TESTING David Herrera alleyinteractive.com

    @dlh01
  2. OUTLINE 1. Unit testing overview 2. Examining a unit test

    3. Testing our own code 4. Unit testing in WordPress
  3. WHAT IS UNIT TESTING? Units = small parts Meeting expectations

  4. UNIT TESTS IN WORDPRESS CORE Reject an u p d

    a t e _ o p t i o n ( ) with an illegal key Set the correct status to future posts Clear the usermeta cache after a user is deleted
  5. WHAT IS PHPUNIT? See also: QUnit

  6. GETTING TO P H P U N I T Next:

    "Setting up Vagrant for Unit Testing" with Paul Bearne
  7. CREATE A PLUGIN WITH UNIT TESTS $ w p s

    c a f f o l d p l u g i n m y - p l u g i n $ l s m y - p l u g i n > b i n m y - p l u g i n . p h p p h p u n i t . x m l r e a d m e . t x t t e s t s
  8. ADD UNIT TEST FILES TO AN EXISTING PLUGIN $ w

    p s c a f f o l d u n i t - t e s t s m y - e x i s t i n g - p l u g i n
  9. RUN THE DEFAULT TEST $ c d m y -

    p l u g i n / $ p h p u n i t
  10. DEFAULT TEST OUTPUT

  11. WHAT WAS THE TEST? < ? p h p /

    / t e s t s / t e s t - s a m p l e . p h p c l a s s S a m p l e T e s t e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t S a m p l e ( ) { / / r e p l a c e t h i s w i t h s o m e a c t u a l t e s t i n g c o d e $ t h i s - > a s s e r t T r u e ( t r u e ) ; } }
  12. THE DEFAULT TEST < ? p h p / /

    t e s t s / t e s t - s a m p l e . p h p f u n c t i o n t e s t S a m p l e ( ) { / / r e p l a c e t h i s w i t h s o m e a c t u a l t e s t i n g c o d e $ t h i s - > a s s e r t T r u e ( t r u e ) ; }
  13. THE DEFAULT TEST (AMENDED) < ? p h p /

    / t e s t s / t e s t - s a m p l e . p h p f u n c t i o n t e s t S a m p l e ( ) { $ f o o = t r u e ; $ t h i s - > a s s e r t T r u e ( $ f o o ) ; }
  14. ASSERTIONS a s s e r t F a l

    s e ( ) a s s e r t E q u a l s ( ) a s s e r t I n t e r n a l T y p e ( ) And many more: a s s e r t A r r a y H a s K e y ( ) a s s e r t C o u n t ( ) a s s e r t E m p t y ( ) a s s e r t F i l e E x i s t s ( ) a s s e r t G r e a t e r T h a n ( ) a s s e r t L e s s T h a n ( ) a s s e r t O b j e c t H a s A t t r i b u t e ( ) phpunit.de/manual
  15. MULTIPLE TESTS < ? p h p c l a

    s s S a m p l e T e s t e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t _ i s _ t r u e ( ) { $ f o o = t r u e ; $ t h i s - > a s s e r t T r u e ( $ f o o ) ; } f u n c t i o n t e s t _ i s _ n u l l ( ) { $ f o o = n u l l ; $ t h i s - > a s s e r t N u l l ( $ f o o ) ; } }
  16. MULTIPLE TESTS OUTPUT

  17. FAILED TESTS < ? p h p c l a

    s s S a m p l e T e s t e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t _ i s _ t r u e ( ) { / * . . . * / } f u n c t i o n t e s t _ i s _ n u l l ( ) { / * . . . * / } f u n c t i o n t e s t _ n a m e s ( ) { $ n a m e = ' W o r d p r e s s ' ; $ t h i s - > a s s e r t E q u a l s ( ' W o r d P r e s s ' , $ n a m e ) ; } }
  18. FAILED TEST OUTPUT

  19. TESTING OUR CODE < ? p h p / /

    m y - p l u g i n . p h p f u n c t i o n s a y _ h e l l o ( $ n a m e ) { r e t u r n s p r i n t f ( _ _ ( ' H e l l o % s ! ' , ' m y - p l u g i n ' ) , $ n a m e ) ; } < ? p h p / / t e s t s / t e s t - s a m p l e . p h p f u n c t i o n t e s t _ s a y _ h e l l o ( ) { $ e x p e c t e d = ' H e l l o , D a v i d ! ' ; $ a c t u a l = s a y _ h e l l o ( ' D a v i d ' ) ; $ t h i s - > a s s e r t E q u a l s ( $ e x p e c t e d , $ a c t u a l ) ; }
  20. CUSTOM CODE OUTPUT

  21. (FIXING THE MISTAKE) < ? p h p / /

    m y - p l u g i n . p h p f u n c t i o n s a y _ h e l l o ( $ n a m e ) { - r e t u r n s p r i n t f ( _ _ ( ' H e l l o % s ! ' , ' m y - p l u g i n ' ) , $ n a m e ) ; + r e t u r n s p r i n t f ( _ _ ( ' H e l l o , % s ! ' , ' m y - p l u g i n ' ) , $ n a m e ) ; }
  22. ROCK PAPER SCISSORS < ? p h p f u

    n c t i o n r o c k _ w i n s ( $ o p p o n e n t ) { i f ( ' s c i s s o r s ' = = s t r t o l o w e r ( $ o p p o n e n t ) ) { r e t u r n t r u e ; } e l s e { r e t u r n f a l s e ; } }
  23. ROCK PAPER SCISSORS < ? p h p c l

    a s s T e s t _ R P S e x t e n d s W P _ U n i t T e s t C a s e { }
  24. ROCK PAPER SCISSORS < ? p h p c l

    a s s T e s t _ R P S e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t _ a g a i n s t _ s c i s s o r s ( ) { $ a c t u a l = r o c k _ w i n s ( ' s c i s s o r s ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; } }
  25. ROCK PAPER SCISSORS < ? p h p c l

    a s s T e s t _ R P S e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t _ a g a i n s t _ s c i s s o r s ( ) { $ a c t u a l = r o c k _ w i n s ( ' s c i s s o r s ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; } f u n c t i o n t e s t _ a g a i n s t _ p a p e r ( ) { $ a c t u a l = r o c k _ w i n s ( ' p a p e r ' ) ; $ t h i s - > a s s e r t F a l s e ( $ a c t u a l ) ; } }
  26. ROCK PAPER SCISSORS < ? p h p c l

    a s s T e s t _ R P S e x t e n d s W P _ U n i t T e s t C a s e { f u n c t i o n t e s t _ a g a i n s t _ s c i s s o r s ( ) { $ a c t u a l = r o c k _ w i n s ( ' s c i s s o r s ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; } f u n c t i o n t e s t _ a g a i n s t _ p a p e r ( ) { $ a c t u a l = r o c k _ w i n s ( ' p a p e r ' ) ; $ t h i s - > a s s e r t F a l s e ( $ a c t u a l ) ; } f u n c t i o n t e s t _ a g a i n s t _ b a n a n a ( ) { $ a c t u a l = r o c k _ w i n s ( ' b a n a n a ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; } }
  27. RPS OUTPUT

  28. ROCK PAPER SCISSORS (FIXED) < ? p h p f

    u n c t i o n r o c k _ w i n s ( $ o p p o n e n t ) { $ v a l i d = a r r a y ( ' r o c k ' , ' p a p e r ' , ' s c i s s o r s ' ) ; $ o p p o n e n t = s t r t o l o w e r ( $ o p p o n e n t ) ; i f ( ! i n _ a r r a y ( $ o p p o n e n t , $ v a l i d ) ) { r e t u r n t r u e ; } r e t u r n ' s c i s s o r s ' = = $ o p p o n e n t ; }
  29. RPS OUTPUT

  30. MAINTAINABLE CODE < ? p h p f u n

    c t i o n r o c k _ w i n s ( $ o p p o n e n t ) { i f ( ! i s _ l e g a l _ t h r o w ( $ o p p o n e n t ) ) { r e t u r n t r u e ; } / / . . . } f u n c t i o n i s _ l e g a l _ t h r o w ( $ o p p o n e n t ) { / / . . . }
  31. SEPARATE TESTS < ? p h p f u n

    c t i o n t e s t _ i s _ l e g a l _ t h r o w ( ) { $ a c t u a l = i s _ l e g a l _ t h r o w ( ' s c i s s o r s ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; $ a c t u a l = i s _ l e g a l _ t h r o w ( ' r o c k ' ) ; $ t h i s - > a s s e r t T r u e ( $ a c t u a l ) ; $ a c t u a l = i s _ l e g a l _ t h r o w ( ' b a n a n a ' ) ; $ t h i s - > a s s e r t F a l s e ( $ a c t u a l ) ; $ a c t u a l = i s _ l e g a l _ t h r o w ( a r r a y ( ' r o c k ' , ' p a p e r ' , ' s c i s s o r s ' ) ) ; $ t h i s - > a s s e r t F a l s e ( $ a c t u a l ) ; / / . . . }
  32. CORE TESTS f u n c t i o n

    t e s t _ b a d _ o p t i o n _ n a m e s ( ) { f o r e a c h ( a r r a y ( ' ' , ' 0 ' , ' ' , 0 , f a l s e , n u l l ) a s $ e m p t y ) { $ t h i s - > a s s e r t F a l s e ( g e t _ o p t i o n ( $ e m p t y ) ) ; $ t h i s - > a s s e r t F a l s e ( a d d _ o p t i o n ( $ e m p t y , ' ' ) ) ; $ t h i s - > a s s e r t F a l s e ( u p d a t e _ o p t i o n ( $ e m p t y , ' ' ) ) ; $ t h i s - > a s s e r t F a l s e ( d e l e t e _ o p t i o n ( $ e m p t y ) ) ; } } f u n c t i o n t e s t _ r e t u r n s _ f a l s e _ i f _ g i v e n _ a n _ i n v a l i d _ e m a i l _ a d d r e s s ( ) { $ d a t a = a r r a y ( " k h a a a a a a a a a a a a a a a n ! " , ' h t t p : / / b o b . e x a m p l e . c o m / ' , " s i f i ' d g i v e u i t , s p a m e r ! 1 " , " c o m . e x a m p l e N O S P A M b o b " , " b o b @ y o u r m o m " ) ; f o r e a c h ( $ d a t a a s $ d a t u m ) { $ t h i s - > a s s e r t F a l s e ( i s _ e m a i l ( $ d a t u m ) , $ d a t u m ) ; } }
  33. W P _ U N I T T E S

    T C A S E
  34. G O _ T O ( ) f u n

    c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ l i n k = g e t _ p o s t _ t y p e _ a r c h i v e _ l i n k ( ' m y - p o s t - t y p e ' ) ; $ t h i s - > g o _ t o ( $ l i n k ) ; }
  35. A S S E R T W P E R

    R O R ( ) f u n c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ r e s p o n s e = w p _ u p d a t e _ p o s t ( a r r a y ( ' I D ' = > ' o o p s ' ) , t r u e ) ; $ t h i s - > a s s e r t W P E r r o r ( $ r e s p o n s e ) ; }
  36. F A C T O R Y - > P

    O S T f u n c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ p o s t _ I D _ A = $ t h i s - > f a c t o r y - > p o s t - > c r e a t e ( ) ; $ p o s t _ I D _ B = $ t h i s - > f a c t o r y - > p o s t - > c r e a t e ( a r r a y ( ' p o s t _ t i t l e ' = > ' H e l l o , T o r o n t o ! ' , ' p o s t _ d a t e ' = > ' 2 0 1 4 - 1 1 - 1 6 0 9 : 3 0 : 0 0 ' , ) ) ; }
  37. F A C T O R Y - > T

    E R M f u n c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ t e r m _ I D _ A = $ t h i s - > f a c t o r y - > t e r m - > c r e a t e ( ) ; $ t e r m _ I D _ B = $ t h i s - > f a c t o r y - > t e r m - > c r e a t e ( a r r a y ( ' n a m e ' = > ' T e r m B ' , ' t a x o n o m y ' = > ' c a t e g o r y ' , ) ) ; }
  38. F A C T O R Y - > U

    S E R f u n c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ u s e r _ I D _ A = $ t h i s - > f a c t o r y - > u s e r - > c r e a t e ( ) ; $ u s e r _ I D _ B = $ t h i s - > f a c t o r y - > u s e r - > c r e a t e ( a r r a y ( ' r o l e ' = > ' s u b s c r i b e r ' , ' d i s p l a y _ n a m e ' = > ' A l d o L e o p o l d ' ) ) ; }
  39. G E T _ E C H O ( )

    f u n c t i o n t e s t _ d e m o n s t r a t i o n s ( ) { $ h a y s t a c k = g e t _ e c h o ( ' t h e _ c o n t e n t ' ) ; $ t h i s - > a s s e r t C o n t a i n s ( ' n e e d l e ' , $ h a y s t a c k ) ; }
  40. MORE RESOURCES Curtis McHale: Getting Started With Unit Tests Pippin

    Williamson: Unit Tests for WordPress Plugins Eric Mann: {12} Needs Unit Tests WPSessions: WordPress Unit Testing Even more at GitHub
  41. THANK YOU