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

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

on

  • 253 views

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb

Statistics

Views

Total Views
253
Slideshare-icon Views on SlideShare
251
Embed Views
2

Actions

Likes
2
Downloads
4
Comments
0

1 Embed 2

http://www.slideee.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb Presentation Transcript

    • SEITENBAU GmbH Christian Baranowski Behavior Driven Development von Web-Applikationen mit Grovvy Spock und Geb
    • 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
    • define behavior given: when: then: some initial context (the givens) an event occurs ensure some outcomes User Story Scenario
    • Gradle Werkzeuge Groovy Spock Geb WebDriver
    • Groovy Klasse package  com.github.tux2323;   ! class  Customer  {   ! } Groovy
    • GroovyVariablen und Methoden class  Customer  {   !   def  foo     String  bar   !   def  doFoo(def  foo){       def  bar     }     boolean  doBar(){       bar     }   } Groovy
    • 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
    • Groovy Maps void  callWithMap()  {        withMap(test:  '123',  name:  '324')   }   ! void  withMap(def  map)  {        map.each  {              key,  value  -­‐>                    println  "${key}:  ${value}"        }   } Groovy
    • Groovy Closures void  callWithClosure()  {        assert  withClosure  {              boolean  result  =  1  ==  1              println  "within  closure  ${result}"              result        }   }   ! def  withClosure(Closure<Boolean>  closure)  {     closure.call()   } Groovy
    • 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
    • • 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?
    • 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
    • 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
    • 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
    • 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
    • Stubbing Setup Verify Teardown Exercise Stub ! ! Create Install Return Values Indirect Inputs SUT xUnit Test Patterns - Gerard Meszaros Spock
    • 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
    • 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
    • Mocking Setup Verify Teardown Exercise Mock Object ! ! ! Create Install Expections Indirect Inputs SUT Record Verify xUnit Test Patterns - Gerard Meszaros Spock
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • Gradle Zusammenfassung Groovy Spock Geb WebDriver
    • 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/