Your SlideShare is downloading. ×
BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

562
views

Published on

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

Published in: Technology, Education

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
562
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. SEITENBAU GmbH Christian Baranowski Behavior Driven Development von Web-Applikationen mit Grovvy Spock und Geb
  • 2. BDD define behavior verify behavior implement unit „BDD behavior-driven development is a specialized version of test- driven development“ - wiki “Behaviour” is a more useful word than “test” - Dan North
  • 3. define behavior given: when: then: some initial context (the givens) an event occurs ensure some outcomes User Story Scenario
  • 4. Gradle Werkzeuge Groovy Spock Geb WebDriver
  • 5. Groovy Klasse package  com.github.tux2323;   ! class  Customer  {   ! } Groovy
  • 6. GroovyVariablen und Methoden class  Customer  {   !   def  foo     String  bar   !   def  doFoo(def  foo){       def  bar     }     boolean  doBar(){       bar     }   } Groovy
  • 7. Groovy Collections void  callWithList(){        withList([1,  1,  2,  3,  5])   }   ! void  withList(def  list)  {        list.each  {              entry  -­‐>                    println  "${entry}"        }        list.eachWithIndex  {              entry,  index  -­‐>                    println  "${index}:  ${entry}"        }   } Groovy
  • 8. Groovy Maps void  callWithMap()  {        withMap(test:  '123',  name:  '324')   }   ! void  withMap(def  map)  {        map.each  {              key,  value  -­‐>                    println  "${key}:  ${value}"        }   } Groovy
  • 9. Groovy Closures void  callWithClosure()  {        assert  withClosure  {              boolean  result  =  1  ==  1              println  "within  closure  ${result}"              result        }   }   ! def  withClosure(Closure<Boolean>  closure)  {     closure.call()   } Groovy
  • 10. Groovy Assertions def  christian  =  new  User(id:  1,  name:  "Christian")   def  martin  =  new  User(id:    1,  name:  "Martin")   assert  christian.name  ==  martin.name christian.name  ==  martin.name   |                  |        |    |            |   |                  |        |    |            Martin   |                  |        |    User{id=1,  basarNumber='null',  name='Martin',  email='null',  lastname='null'}   |                  |        false   |                  |        5  differences  (44%  similarity)   |                  |        (Ch)r(is)ti(a)n   |                  |        (Ma)r(-­‐-­‐)ti(-­‐)n   |                  Christian   User{id=1,  basarNumber='null',  name='Christian',  email='null',  lastname='null'} Groovy
  • 11. • Sehr einfaches BDD Werkzeug für die JVM, kann schnell erlernt werden • Biete eine ausdrucksstarke DSL zur Spezifikation von Tests, insbesondere für Parametrisierte Tests (Data Driven Tests) • Spock kann sowohl für Unit- wie Systemtests genutzt werden • JUnit Kompatibel - Zur Ausführung wird JUnit genutzt, • Spock vereint die besten Features aus bewährten Tools wie JUnit, JMock und RSpec Warum Spock?
  • 12. Spock Given When Then def  "spock  test  with  given  when  then  block"()  {        given:  "Array  with  one  element"                def  data  =  ["Some  Data"]        when:  "Pop  a  element  from  the  array"                data.pop()        then:  "Size  of  the  array  is  zero"                data.size()  ==  0   } Spock
  • 13. Blocks given: when: then: and: setup: expect: cleanup: Vorbedingung, Data Fixtures, Setup Zustand SUT wird verändert Assertions, Prüfung des neuen Zustands Kurzvariante für when & then Unterteilung in weitere Blöcke Alias für den given Block Cleanup innerhalb eines Tests Spock
  • 14. Blocks def  "spock  test  with  some  blocks"()  {                  given:                            def  basar  =  Mock(Basar)                          basar.getTotal()  >>  100L                  when:                          def  total  =  basar.getTotal()                  then:                          total  ==  100L                  and:                          def  user  =  basar.findUserWithId(100)                  then:                          user  ==  null                  cleanup:                          basar  =  null   } Spock
  • 15. Lifecycle class  LifecycleSpec  extends  Specification  {          def  setupSpec()  {    println  "01  -­‐  setup  Spec"  }          def  setup()  {  println  "02  -­‐  setup"  }          def  "simple  spock  test"()  {                  given:   println  "02  -­‐  setup  test"     expect:                          def  data  =  []          data  ==  []   cleanup:   println  "04  -­‐  cleanup  test"          }   !        def  cleanup()  {  println  "04  -­‐  cleanup"  }          def  cleanupSpec()  {  println  "04  -­‐  cleanup  Spec"  }   } Spock
  • 16. Stubbing Setup Verify Teardown Exercise Stub ! ! Create Install Return Values Indirect Inputs SUT xUnit Test Patterns - Gerard Meszaros Spock
  • 17. Stubbing mockService.findByName(  'max'  )  >>  'OK'   mockService.findByName(  'max'  )  >>  'OK'  >>  'ERR'   mockService.findByName(  'max'  )  >>>  ['OK',  'ERROR',  'ups']       mockService.findByName(  'max'  )  >>  {  throw  new  InternalError()  }   ! mockService.findByName(  _  )  >>  'OK'   mockService.findByName(  _  )  >>  {name  -­‐>  name.size()  >  1  ?  'OK'  :  'ERR'} mockService.findByName(  'max'  )  >>  'OK' method constraint argument constraint response generator responsegenerator def  mockService  =  Mock(SellerService)         Spock
  • 18. Stubbing  def  "cache  should  return  result  of  the  target"()  {        given:  "a  mock  service  object  that  returns  OK"        def  mockService  =  Mock(SellerService)                mockService.findByName('max')  >>  'OK'  >>  {  throw  exception()  }        and:  "cache  with  the  mock  object  as  target"        def  cache  =  new  SimpleCache(target:  mockService)              when:  "invoke  cache  the  first  time"        def  result  =  cache.findByName('max')        then:  "result  is  OK"        result  ==  'OK'        when:  "invoke  cache  the  second  time"        result  =  cache.findByName('max')        then:  "result  is  OK"        result  ==  'OK'   } Spock
  • 19. Mocking Setup Verify Teardown Exercise Mock Object ! ! ! Create Install Expections Indirect Inputs SUT Record Verify xUnit Test Patterns - Gerard Meszaros Spock
  • 20. Mocking 1  *            mockService.findByName(  'max'  ) cardinality method constraint argument constraint cardinality method constraint argument constraint def  mockService  =  Mock(SellerService)         1  *            mockService.findByName(  'max'  )   (0..1)  *  mockService.findByName(  'max'  )   (1.._)  *  mockService.findByName(  'max'  )   _  *  mockService.findByName(  'max'  ) 1  *            mockService.findByName(  _  )   1  *            mockService.findByName(  !null  )   1  *            mockService.findByName(  !'max'  )   1  *            mockService.findByName(  {  it.size()  >  0  }  ) 1  *            mockService._(  *_  )   0  *            mockService._ Spock
  • 21. Mocking Example def  "only  the  first  call  should  be  forwarded"()  {      given:          def  mockService  =  Mock(SellerService)                          def  cache  =  new  SimpleCache(target:  mockService)                      when:  "invoke  two  times  the  cached  method"          cache.findByName('max')          cache.findByName('max')      then:  "target  method  was  invoked  one  time"          1  *  mockService.findByName('max')   } Spock
  • 22. Parameterized Test @Unroll   def  "edit  seller  '#basarNumber',  '#name'  and  '#lastname'"()  {        when:            def  updatedUser  =  updateUser(basarNumber,  name,  lastname)        then:            updatedUser.basarNumber  ==  basarNumber            updatedUser.name  ==  name            updatedUser.lastname  ==  lastname        where:                      basarNumber    |  name                  |      lastname                      "100"                |  "Christian"    |      "Baranowski"                      "ABC"                |  "Christian"    |      "Baranowski"                      "100"                |  ""                      |      "Baranowski"                      "100"                |  "Christian"    |      ""   } Spock
  • 23. Parameterized Test @Unroll   def  "create  a  #user"()  {        when:            basar.saveUser(user)        then:            basar.findUserWithId(user.id)  ==  user        where:            user  <<  [new  User(id:  1),  new  User(id:  2),  new  User(id:  3)]   } Spock
  • 24. Warum Geb? • Geb bietet eine Abstraktion undVereinfachung der WebDriver API für Groovy • Dazu werden die dyamischen Sprachfunktionen von Groovy genutzt. • JQuery like API für Selenium WebDriver • Geb bietet einen Mechanismus zur Seitenabstraktion 
 lesbare Oberflächentests • Einfacher waitFor{ } mir Groovy Closure für dynamische Web-Anwendungen • Groovy GString bietet einfache JavaScript Integration in Tests Geb WebDriver
  • 25. Geb „JQuery like API“ $(«css  selector»,  «index  or  range»,  «attribute  /  text  matchers») $('div.span8  p')   $('#newUserButton')   $('.error') $('div',  2,  class:  'span2')   $('div',  0..2,  class:  'span2') $('button',  class:  'btn')   $('td',  text:  '559')   $('td',  text:  contains('55'))   $('input',  value:  ~/.*/) $('div').find('.span8') selector index  or  range attribute  /     text  matchers Finding Geb WebDriver
  • 26. Geb „JQuery like API“ $('div').parent()   $('div').next()   $('div').siblings()   $('div').children()   ! $('td',  text:  '559').parent().find('td')   $('td',  text:  '559').parent().children() Traversing Geb WebDriver
  • 27. Geb waitFor //  use  default  wait  configuration   waitFor  {          sellerCountBefore  <  sellerCount()     }   ! //  wait  for  up  to  10  seconds,  using  the  default  retry  interval   waitFor(10)  {          sellerCountBefore  <  sellerCount()     }   waitFor(timeout=20)  {  $("#newUser")  }   ! //  wait  for  up  to  10  seconds,  waiting  half  a  second  between  retries   waitFor(10,  0.5)  {          sellerCountBefore  <  sellerCount()     }   ! //  custom  message   waitFor(message:  'Button  not  found',  timeout=2)  {   $("#NewUserButton")   } Geb WebDriver
  • 28. Gradle Zusammenfassung Groovy Spock Geb WebDriver
  • 29. Links • Spock - http://spockframework.org • Spock GitHub - https://github.com/spockframework • Spock Framework Reference Documentation 
 http://docs.spockframework.org/en/latest/ • Geb - http://www.gebish.org/