Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Spock and Geb in Action
Christian Baranowski
Tools
Groovy
Tools
Groovy Spock
www.spockframework.org
Tools
Groovy Spock Geb
www.spockframework.org
www.gebish.org
Tools
Groovy Spock Geb
WebDriver
Selenium
www.spockframework.org
www.gebish.org
Warum Spock?
Warum Spock?
1. Spock ist ein einfaches
BDD Werkzeug für die JVM
weitere Argumente ...
2. Spock biete ausdrucksstarke DSL zur
Spezifikation von Tests, insbesondere für
Parametrisierte Tests und Mocking
weitere ...
2. Spock biete ausdrucksstarke DSL zur
Spezifikation von Tests, insbesondere für
Parametrisierte Tests und Mocking
3. Spock...
2. Spock biete ausdrucksstarke DSL zur
Spezifikation von Tests, insbesondere für
Parametrisierte Tests und Mocking
3. Spock...
2. Spock biete ausdrucksstarke DSL zur
Spezifikation von Tests, insbesondere für
Parametrisierte Tests und Mocking
3. Spock...
Spock Given When Then
Spock Given When Then
def	
  "spock	
  test	
  with	
  given	
  when	
  then	
  block"()	
  {
	
  	
  	
  given:	
  "Array...
Spock Blocks
given:
when:
then:
and:
setup:
expect:
cleanup:
Vorbedingung, Data Fixtures, Setup
Zustand SUT wird verändert...
Spock Blocks in Action
def	
  "spock	
  test	
  with	
  some	
  blocks"()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  given:	
  
...
Vier Phasen Test (Four-Phase Test)
SUT
xUnit Test Patterns - Gerard Meszaros
Vier Phasen Test (Four-Phase Test)
Setup Fixure
1
def	
  setupSpec()	
  {}
def	
  setup()	
  {}
SUT
xUnit Test Patterns - ...
Vier Phasen Test (Four-Phase Test)
Setup
Exercise
SUT
Fixure
1
2
def	
  setupSpec()	
  {}
def	
  setup()	
  {}
when:
def	
...
Vier Phasen Test (Four-Phase Test)
Setup
Verify
Exercise
SUT
Fixure
1
2
3
def	
  setupSpec()	
  {}
def	
  setup()	
  {}
wh...
Vier Phasen Test (Four-Phase Test)
Setup
Verify
Teardown
Exercise
SUT
Fixure
1
2
3
4
def	
  setupSpec()	
  {}
def	
  setup...
Spock Lifecycle
class	
  LifecycleSpec	
  extends	
  Specification	
  {
	
  	
  	
  	
  def	
  setupSpec()	
  {	
  	
  pri...
def	
  christian	
  =	
  new	
  User(id:	
  1,	
  name:	
  "Christian")
def	
  martin	
  =	
  new	
  User(id:	
  	
  1,	
 ...
def	
  christian	
  =	
  new	
  User(id:	
  1,	
  name:	
  "Christian")
def	
  martin	
  =	
  new	
  User(id:	
  	
  1,	
 ...
Mocking
Setup
Verify
Teardown
Exercise
Mock
Object
Create
Install
Expections
Indirect
Inputs
SUT
Record
Verify
xUnit Test ...
Mocking
1	
  *	
  	
  	
  	
  	
  	
  mockService.findByName(	
  'max'	
  )
def	
  mockService	
  =	
  Mock(SellerService)...
Mocking
1	
  *	
  	
  	
  	
  	
  	
  mockService.findByName(	
  'max'	
  )
cardinality
cardinality
def	
  mockService	
  ...
Mocking
1	
  *	
  	
  	
  	
  	
  	
  mockService.findByName(	
  'max'	
  )
cardinality method constraint
cardinality
meth...
Mocking
1	
  *	
  	
  	
  	
  	
  	
  mockService.findByName(	
  'max'	
  )
cardinality method constraint argument constra...
def	
  "only	
  the	
  first	
  call	
  should	
  be	
  forwarded"()	
  {
	
  	
  given:
	
  	
  	
  	
  def	
  mockServic...
Stubbing
Setup
Verify
Teardown
Exercise
Stub
Create
Install
Return
Values
Indirect
Inputs
SUT
xUnit Test Patterns - Gerard...
Stubbing
mockService.findByName(	
  'max'	
  )	
  >>	
  'OK'
def	
  mockService	
  =	
  Mock(SellerService)	
  	
  	
  	
  
Stubbing
mockService.findByName(	
  'max'	
  )	
  >>	
  'OK'
method constraint
def	
  mockService	
  =	
  Mock(SellerServi...
Stubbing
mockService.findByName(	
  'max'	
  )	
  >>	
  'OK'
method constraint argument constraint
def	
  mockService	
  =...
Stubbing
mockService.findByName(	
  'max'	
  )	
  >>	
  'OK'
mockService.findByName(	
  'max'	
  )	
  >>	
  'OK'	
  >>	
  ...
 def	
  "cache	
  should	
  return	
  result	
  of	
  the	
  target"()	
  {
	
  	
  	
  given:	
  "a	
  mock	
  service	
 ...
Parameterized Test (I)
Parameterized Test (I)
@Unroll
def	
  "edit	
  seller	
  '#basarNumber',	
  '#name'	
  and	
  '#lastname'"()	
  {
	
  	
  ...
@Unroll
def	
  "edit	
  seller	
  '#basarNumber',	
  '#name'	
  and	
  '#lastname'"()	
  {
	
  	
  ...	
  
	
  	
  where:
...
@Unroll
def	
  "create	
  a	
  #user"()	
  {
	
  	
  	
  when:
	
  	
  	
  	
  	
  basar.saveUser(user)
	
  	
  	
  then:
...
Warum Geb?
•Geb bietet eine Abstraktion undVereinfachung der
WebDriver API
•Dazu werden die dyamischen Sprachfunktionen vo...
Geb „JQuery like API“
$(«css	
  selector»,	
  «index	
  or	
  range»,	
  «attribute	
  /	
  text	
  matchers»)
Geb „JQuery like API“
$(«css	
  selector»,	
  «index	
  or	
  range»,	
  «attribute	
  /	
  text	
  matchers»)
$('div.span...
Geb „JQuery like API“
$(«css	
  selector»,	
  «index	
  or	
  range»,	
  «attribute	
  /	
  text	
  matchers»)
$('div.span...
Geb „JQuery like API“
$(«css	
  selector»,	
  «index	
  or	
  range»,	
  «attribute	
  /	
  text	
  matchers»)
$('div.span...
Geb „JQuery like API“
$(«css	
  selector»,	
  «index	
  or	
  range»,	
  «attribute	
  /	
  text	
  matchers»)
$('div.span...
Geb „JQuery like API“
$('div').parent()
$('div').next()
$('div').siblings()
$('div').children()
$('td',	
  text:	
  '559')...
Geb „JQuery like API“
$('#newUser').@id	
  	
  	
  	
  	
  	
  	
  	
  ==	
  'newUser'
$('#newUser').attr('id')	
  ==	
  '...
Geb waitFor API
//	
  use	
  default	
  wait	
  configuration
waitFor	
  {	
  
	
  	
  	
  sellerCountBefore	
  <	
  selle...
Page Object Pattern
import	
  geb.Page
	
  	
  	
  	
  	
  
class	
  BasarPage	
  extends	
  Page	
  {
	
  	
  	
  	
  sta...
Page Object Pattern
import	
  geb.Page
	
  	
  	
  	
  	
  
class	
  BasarPage	
  extends	
  Page	
  {
	
  	
  	
  	
  sta...
Action Test
def	
  "add	
  a	
  item	
  to	
  the	
  cart"()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  given:
	
  	
  	
  	
  	...
class	
  BasarBind	
  extends	
  Bind	
  {
	
  	
  	
  	
  def	
  start()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  go	
  "/sta...
Test Design
Test
Test Design
Test
Logik
Test Design
Test
Logik
Spock Framework
Test Design
Test
Logik
Binding SUT
Spock Framework
Test Design
Test
Logik
Binding SUT
Spock Framework
Page Object Pattern
Test Design
Test
Logik
Binding SUT
Spock Framework
Page Object Pattern
Action Test Pattern
Test Design
Test
Daten
Logik
Binding SUT
Spock Framework
Page Object Pattern
Action Test Pattern
Test Design
Test
Daten
Logik
Binding SUT
Spock Framework
Page Object PatternbasarNumber	
  	
  |	
  name	
  	
  	
  	
  	
...
Spock and Geb in Action
Upcoming SlideShare
Loading in …5
×

Spock and Geb in Action

3,927 views

Published on

Published in: Technology, Business

Spock and Geb in Action

  1. 1. Spock and Geb in Action Christian Baranowski
  2. 2. Tools Groovy
  3. 3. Tools Groovy Spock www.spockframework.org
  4. 4. Tools Groovy Spock Geb www.spockframework.org www.gebish.org
  5. 5. Tools Groovy Spock Geb WebDriver Selenium www.spockframework.org www.gebish.org
  6. 6. Warum Spock?
  7. 7. Warum Spock? 1. Spock ist ein einfaches BDD Werkzeug für die JVM
  8. 8. weitere Argumente ...
  9. 9. 2. Spock biete ausdrucksstarke DSL zur Spezifikation von Tests, insbesondere für Parametrisierte Tests und Mocking weitere Argumente ...
  10. 10. 2. Spock biete ausdrucksstarke DSL zur Spezifikation von Tests, insbesondere für Parametrisierte Tests und Mocking 3. Spock kann sowohl für Unit- wie Systemtests genutzt werden weitere Argumente ...
  11. 11. 2. Spock biete ausdrucksstarke DSL zur Spezifikation von Tests, insbesondere für Parametrisierte Tests und Mocking 3. Spock kann sowohl für Unit- wie Systemtests genutzt werden 4. JUnit Kompatibel - Zur Ausführung wird JUnit genutzt, Integration in IDEs, Build-Tools (Ant, Maven, Gradle...) und CI (Jenkins) weitere Argumente ...
  12. 12. 2. Spock biete ausdrucksstarke DSL zur Spezifikation von Tests, insbesondere für Parametrisierte Tests und Mocking 3. Spock kann sowohl für Unit- wie Systemtests genutzt werden 4. JUnit Kompatibel - Zur Ausführung wird JUnit genutzt, Integration in IDEs, Build-Tools (Ant, Maven, Gradle...) und CI (Jenkins) 5. Spock vereint die besten Features aus bewährten Tools wie JUnit und RSpec weitere Argumente ...
  13. 13. Spock Given When Then
  14. 14. 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 }
  15. 15. 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
  16. 16. Spock Blocks in Action 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 }
  17. 17. Vier Phasen Test (Four-Phase Test) SUT xUnit Test Patterns - Gerard Meszaros
  18. 18. Vier Phasen Test (Four-Phase Test) Setup Fixure 1 def  setupSpec()  {} def  setup()  {} SUT xUnit Test Patterns - Gerard Meszaros
  19. 19. Vier Phasen Test (Four-Phase Test) Setup Exercise SUT Fixure 1 2 def  setupSpec()  {} def  setup()  {} when: def  "spock  test"()  {   SUT xUnit Test Patterns - Gerard Meszaros
  20. 20. Vier Phasen Test (Four-Phase Test) Setup Verify Exercise SUT Fixure 1 2 3 def  setupSpec()  {} def  setup()  {} when: def  "spock  test"()  {   then: } SUT xUnit Test Patterns - Gerard Meszaros
  21. 21. Vier Phasen Test (Four-Phase Test) Setup Verify Teardown Exercise SUT Fixure 1 2 3 4 def  setupSpec()  {} def  setup()  {} when: def  cleanup()  {} def  cleanupSpec()  {} def  "spock  test"()  {   then: } SUT xUnit Test Patterns - Gerard Meszaros
  22. 22. 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"  } }
  23. 23. 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 Power Assertion
  24. 24. 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'} Im then: block Kurzschreibweise möglich ohne assert Groovy Power Assertion
  25. 25. Mocking Setup Verify Teardown Exercise Mock Object Create Install Expections Indirect Inputs SUT Record Verify xUnit Test Patterns - Gerard Meszaros
  26. 26. Mocking 1  *            mockService.findByName(  'max'  ) def  mockService  =  Mock(SellerService)        
  27. 27. Mocking 1  *            mockService.findByName(  'max'  ) cardinality cardinality def  mockService  =  Mock(SellerService)         1  *            mockService.findByName(  'max'  ) (0..1)  *  mockService.findByName(  'max'  ) (1.._)  *  mockService.findByName(  'max'  ) _  *  mockService.findByName(  'max'  )
  28. 28. Mocking 1  *            mockService.findByName(  'max'  ) cardinality method constraint cardinality method constraint def  mockService  =  Mock(SellerService)         1  *            mockService.findByName(  'max'  ) (0..1)  *  mockService.findByName(  'max'  ) (1.._)  *  mockService.findByName(  'max'  ) _  *  mockService.findByName(  'max'  ) 1  *            mockService._(  *_  ) 0  *            mockService._
  29. 29. 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._
  30. 30. 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') } Mocking Example
  31. 31. Stubbing Setup Verify Teardown Exercise Stub Create Install Return Values Indirect Inputs SUT xUnit Test Patterns - Gerard Meszaros
  32. 32. Stubbing mockService.findByName(  'max'  )  >>  'OK' def  mockService  =  Mock(SellerService)        
  33. 33. Stubbing mockService.findByName(  'max'  )  >>  'OK' method constraint def  mockService  =  Mock(SellerService)        
  34. 34. Stubbing mockService.findByName(  'max'  )  >>  'OK' method constraint argument constraint def  mockService  =  Mock(SellerService)        
  35. 35. 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)        
  36. 36.  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' } Stubbing Example
  37. 37. Parameterized Test (I)
  38. 38. Parameterized Test (I) @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"    |      "" }
  39. 39. @Unroll def  "edit  seller  '#basarNumber',  '#name'  and  '#lastname'"()  {    ...      where:                basarNumber    |  name                  |      lastname                "100"                |  "Christian"    |      "Baranowski"                "ABC"                |  "Christian"    |      "Baranowski"                "100"                |  ""                      |      "Baranowski"                "100"                |  "Christian"    |      "" } Parameterized Test (I)
  40. 40. @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)] } Parameterized Test (II)
  41. 41. Warum Geb? •Geb bietet eine Abstraktion undVereinfachung der WebDriver API •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 •einfache JavaScript Integration für Testanbindung
  42. 42. Geb „JQuery like API“ $(«css  selector»,  «index  or  range»,  «attribute  /  text  matchers»)
  43. 43. Geb „JQuery like API“ $(«css  selector»,  «index  or  range»,  «attribute  /  text  matchers») $('div.span8  p') $('#newUserButton') $('.error') selector
  44. 44. 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') selector index  or  range
  45. 45. 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:  ~/.*/) selector index  or  range attribute  /   text  matchers
  46. 46. 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
  47. 47. Geb „JQuery like API“ $('div').parent() $('div').next() $('div').siblings() $('div').children() $('td',  text:  '559').parent().find('td') $('td',  text:  '559').parent().children() Traversing
  48. 48. Geb „JQuery like API“ $('#newUser').@id                ==  'newUser' $('#newUser').attr('id')  ==  'newUser' $('#newUser').text()          ==  'Neuen  Nutzer  anlegen' $('#newUser').tag()            ==  'button' $('#newUser').classes()    ==  ['btn',  'updateUserButton'] $('button')*.text()            ==  ['Löschen',  'Neuen  Nutzer'] $('#newUser').click() $('input',  name:  'basarNumber').value('100') $('div.desc')  <<  'X' $('input',  name:  'basarNumber')  <<  '100' Accessing Attributes clicking input  values Sending   keystrokes
  49. 49. Geb waitFor API //  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") }
  50. 50. Page Object Pattern import  geb.Page           class  BasarPage  extends  Page  {        static  url  =  "static/basar.html"        static  at  =  {  title  ==  "Basar"  }        static  content  =  {                basarForm  {  $("form")  }                addButton  (to:  BasarPage)  {  basarForm.addCartItem()  }        } }
  51. 51. Page Object Pattern import  geb.Page           class  BasarPage  extends  Page  {        static  url  =  "static/basar.html"        static  at  =  {  title  ==  "Basar"  }        static  content  =  {                basarForm  {  $("form")  }                addButton  (to:  BasarPage)  {  basarForm.addCartItem()  }        } } Browser.drive  {        to  BasarPage        assert  at(BasarPage)        basarForm.with  {                basarNumber  =  "100"                price  =  "10,50"        }        addButton.click() } // Test (Test Logik)
  52. 52. Action Test def  "add  a  item  to  the  cart"()  {                given:                BasarBind  basar  =  start  BasarBind                when:                basar  {                      enter  '100'  into  basarNumberField                      enter  '0,50'  into  priceField                      click  addButton                }                then:                basar.sum  ==  '0,50' } https://github.com/tux2323/gebbind
  53. 53. class  BasarBind  extends  Bind  {        def  start()  {                go  "/static/basar.html"                waitFor  {  title  ==  "Basar"  }        }        InputText  basarNumberField  =  inputText  {  $("#basarNumber")  }    InputText  priceField  =  inputText  {  $("#price")  }        Button  addButton  =  button  onClick:  {                def  beforeClickCartSize  =  $('tr').size()                $('#addCartItem').click()                waitFor  {                        $('tr').size()  >  beforeClickCartSize  ||                        $('.text-­‐error').size()  >  0                }        } Text  sum  =  text  {  $('#sum')  } } Action Test https://github.com/tux2323/gebbind
  54. 54. Test Design Test
  55. 55. Test Design Test Logik
  56. 56. Test Design Test Logik Spock Framework
  57. 57. Test Design Test Logik Binding SUT Spock Framework
  58. 58. Test Design Test Logik Binding SUT Spock Framework Page Object Pattern
  59. 59. Test Design Test Logik Binding SUT Spock Framework Page Object Pattern Action Test Pattern
  60. 60. Test Design Test Daten Logik Binding SUT Spock Framework Page Object Pattern Action Test Pattern
  61. 61. Test Design Test Daten Logik Binding SUT Spock Framework Page Object PatternbasarNumber    |  name                  ||      lastname "100"                |  "Christian"    ||      "Baranowski" "ABC"                |  "Christian"    ||      "Baranowski" "100"                |  ""                      ||      "Baranowski" "100"                |  "Christian"    ||      "" Parameterized Test Action Test Pattern

×