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

Gordon Franke

March 18, 2013
Tweet

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 >