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

Testing Like A Boss

Testing Like A Boss

See also http://www.rvl.io/gimler/behat-mink-phantomjs original slides with working text copy and links

Avatar for Gordon Franke

Gordon Franke

March 18, 2013
Tweet

More Decks by Gordon Franke

Other Decks in Programming

Transcript

  1. TESTING LIKE A BOSS BEHAT + MINK + GOUTTE +

    BEHATCH + PHANTOMJS + JENKINS = BINGO
  2. BEHAT Zero Project dependencies Readable by everybody Open Source Well

    documented Active Community Inspired by Ruby Cucumber
  3. CONFIGURATION All is done in one file behat.yml d e

    f a u l t : p a t h s : f e a t u r e s : f e a t u r e s c o n t e x t : c l a s s : Y o u r \ C u s t o m \ C o n t e x t w i p : f i l t e r s : t a g s : " @ w i p " f o r m a t t e r : n a m e : p r o g r e s s
  4. INSTALLATION I First install composer Build composer.json with bin config

    option Install all required packages c u r l h t t p : / / g e t c o m p o s e r . o r g / i n s t a l l e r | p h p p h p c o m p o s e r . p h a r i n s t a l l - - p r e f e r - s o u r c e p h p c o m p o s e r . p h a r i n i t - n p h p c o m p o s e r . p h a r c o n f i g b i n - d i r " b i n / " p h p c o m p o s e r . p h a r r e q u i r e " b e h a t / b e h a t : 2 . 4 . * @ s t a b l e " " b e h a t / m i n k : 1 . 4 . * @ s t a b l e " " b e h a t / m i n k - g o u t t e - d r i v e r : d e v - m a s t e r " " b e h a t / m i n k - s e l e n i u m 2 - d r i v e r : d e v - m a s t e r " " b e h a t / m i n k - e x t e n s i o n : d e v - m a s t e r " " s a n p i / b e h a t c h - c o n t e x t s : d e v - m a s t e r "
  5. INSTALLATION II Create behat.yml with configuration d e f a

    u l t : e x t e n s i o n s : B e h a t \ M i n k E x t e n s i o n \ E x t e n s i o n : b a s e _ u r l : ' h t t p : / / w w w . m y - h a m m e r . d e ' d e f a u l t _ s e s s i o n : g o u t t e j a v a s c r i p t _ s e s s i o n : s e l e n i u m 2 g o u t t e : ~ s e l e n i u m 2 : w d _ h o s t : " h t t p : / / l o c a l h o s t : 8 6 4 3 / w d / h u b " S a n p i \ B e h a t c h \ E x t e n s i o n : c o n t e x t s : b r o w s e r : ~ s y s t e m : ~ j s o n : ~ t a b l e : ~ r e s t : ~
  6. INSTALLATION III Initialize behat Load additional context into your context

    (features/bootstrap/FeatureContext.php) b i n / b e h a t - - i n i t p u b l i c f u n c t i o n _ _ c o n s t r u c t ( a r r a y $ p a r a m e t e r s ) { $ t h i s - > u s e C o n t e x t ( ' b e h a t c h ' , n e w B e h a t c h C o n t e x t ( $ p a r a m e t e r s ) ) ; }
  7. STRUCTURE [ F e a t u r e |

    B u s i n e s s N e e d | A b i l i t y ] : I n t e r n a l o p e r a t i o n s . . . B a c k g r o u n d : G i v e n t h e r e i s a g e n t A S c e n a r i o : E r a s i n g a g e n t m e m o r y [ G i v e n | A n d | W h e n | T h e n | B u t ] t h e r e i s a g e n t J [ S c e n a r i o O u t l i n e | S c e n a r i o T e m p l a t e ] : E r a s i n g o t h e r a g e n t s ' m e m o r y G i v e n t h e r e i s < a g e n t 1 > [ E x a m p l e s | S c e n a r i o s ] : | a g e n t 1 | a g e n t 2 | | D | M |
  8. WRITING YOUR FIRST TEST # l a n g u

    a g e : e n F e a t u r e : H o m e p a g e A s u s e r i w a n t s e a r c h f o r j o b s . B a c k g r o u n d : G i v e n i a m o n " / " @ j a v a s c r i p t S c e n a r i o : S e a r c h b o x v a l i d a t i o n A n d p r e s s " S e a r c h " T h e n s h o u l d s e e " P l e a s e p r o v i d e a s e a r c h t e r m . "
  9. RUNNING TESTS Start all tests Start specific feature Start specific

    feature szenario b i n / b e h a t b i n / b e h a t f e a t u r e s / m y . f e a t u r e b i n / b e h a t f e a t u r e s / m y . f e a t u r e : 3
  10. OUTPUT Feature: Homepage As user i want search for jobs.

    Background: Given I am on "/" @javascript Scenario: Searchbox validation And press "Suchen" Then should see "Bitte geben Sie an \"was\" oder \"wo\" Sie suchen." 1 Szenario (1 bestanden) 3 Schritte (3 bestanden) 0m4.349s
  11. TIPS Story syntax in your language All available commands in

    your language Filter commands with grep Make your Elements accessable with ID or CSS-Class b i n / b e h a t - - s t o r y - s y n t a x - - l a n g = d e b i n / b e h a t - - l a n g = d e - d i b i n / b e h a t - - l a n g = d e - d i | g r e p " s e h e n " - A 1 < d i v i d = " s e a r c h - f i l t e r " > < d i v i d = " s e a r c h - p a g i n a - t o p " c l a s s = " s e a r c h - p a g i n a " >
  12. TIPS Proxy Handling Access form fields via id, css, xpath

    selector or label text Zombie.js has problems with document.write see (https://github.com/assaf/zombie/issues/437) and d e v : e x t e n s i o n s : B e h a t \ M i n k E x t e n s i o n \ E x t e n s i o n : g o u t t e : g u z z l e _ p a r a m e t e r s : " c u r l . o p t i o n s " : C U R L O P T _ P R O X Y : " 1 7 2 . 1 6 . 1 6 . 1 0 : 8 8 8 8 " Symfony2 Framework Extension Yii Framework Extension
  13. EXTEND In your Context define a method To translate it

    in your langauge create de.xliff under /i18n / * * * @ T h e n / ^ ( ? : | I ) s h o u l d s e e ( \ d + ) - ( \ d + ) " ( [ ^ " ] * ) " e l e m e n t s ? $ / * / p u b l i c f u n c t i o n s h o u l d S e e N u m T o N u m E l e m e n t s ( $ n u m 1 , $ n u m 2 , $ e l e m e n t ) { $ n o d e s = $ t h i s - > g e t M i n k ( ) - > g e t S e s s i o n ( ) - > g e t P a g e ( ) - > f i n d A l l ( ' c s s ' , $ e l e m e n t ) ; i f ( c o u n t ( $ n o d e s ) > $ n u m 2 | | c o u n t ( $ n o d e s ) < $ n u m 1 ) { t h r o w n e w F o r m a t t e r E x c e p t i o n ( " g o t " . c o u n t ( $ n o d e s ) . " n o d e s w h e r e i t s h o u l d b e b e t w e e n " . $ n u m 1 . " a n d " . $ n u m 2 ) ; } } < t r a n s - u n i t i d = " s h o u l d - s e e - n - n - e l e m e n t s " > < s o u r c e > < ! - - [ C D A T A [ / ^ ( ? : | I ) s h o u l d s e e ( \ d + ) - ( \ d + ) " ( [ ^ " ] * ) " e l e m e n t s ? $ / ] ] - - > < / s o u r c e > < t a r g e t > < ! - - [ C D A T A [ / ^ ( ? : | i c h ) s o l l t e ( ? : | i c h ) ( \ d + ) - ( \ d + ) " ( [ ^ " ] * ) " E l e m e n t e s e h e n ] ] - - > < / t a r g e t > < / t r a n s >
  14. PHANTOMJS There is no driver for PhantomJS but we can

    use selenium2 driver (behat.yml) Use driver for specific szenario Start PhantomJS server d e f a u l t : e x t e n s i o n s : B e h a t \ M i n k E x t e n s i o n \ E x t e n s i o n : j a v a s c r i p t _ s e s s i o n : s e l e n i u m 2 s e l e n i u m 2 : w d _ h o s t : " h t t p : / / l o c a l h o s t : 8 6 4 3 / w d / h u b " . . . @ j a v a s c r i p t S z e n a r i o : L o g i n p h a n t o m j s - - w e b d r i v e r = 8 6 4 3 - - p r o x y = i p : p o r t
  15. JENKINS Profile Ant build step c i _ l o

    c a l : f o r m a t t e r : n a m e : j u n i t , p r o g r e s s < t a r g e t n a m e = " b e h a t " d e s c r i p t i o n = " R u n B e h a t " > < c h m o d f i l e = " $ { e n v . W O R K S P A C E } / b i n / b e h a t " p e r m = " + x " / > < e x e c e x e c u t a b l e = " b i n / b e h a t " f a i l o n e r r o r = " t r u e " d i r = " $ { e n v . W O R K S P A C E } " > < ! - - o u t m u s t d e f i n e p a t h f o r e v e r y f o r m a t e r ( , = > e m p t y = > c l i ) - - > < a r g l i n e = " - - p r o f i l e = c i - - o u t = ' $ { b a s e d i r } / b u i l d / l o g s / b e h a t / , ' " / > < / e x e c > < / t a r g e t >