G*


      2010/07/24 g*workshop
     takuma.watabiki@jggug.org
✤


✤


✤       Grails/Groovy


✤   Java

✤   twitter   @bikisuke
G*
TDD
            C)



TDD
-         BDD        -
                C)



    TDD
Ora

  C)
✤   BDD     Spock

✤   Spock 0.4

✤   Spock
BDD   Spock
BDD
✤   Behaviour Driven Development


✤   2003    Dan North

✤
BDD

✤



✤


✤   BDD


✤
✤   As a

✤   I want

✤   so that
✤   Given

✤   When

✤   Then
Spock

✤   Java   Groovy
    BDD

✤   Java / Groovy   JUnit


✤   Data Driven

✤
✤   Java 5

✤   Groovy 1.6   or 1.7

✤   JUnit 4.4
✤                                    IDE


    ✤                 Ant, Maven, Gradle
    ✤   IDE   Eclipse / STS, IntelliJ IDEA
    ✤           GAE

        http://meetspock.appspot.com/
Hello Spock
                                     Specification
import spock.lang.*

class HelloSpock extends spock.lang.Specification {

  def cleanup() {
	   println '                    '
    }
    def "                    "() {
        expect:
        name.size() == length

        where:
        name      | length
        "Spock"   | 5
    }
}
BDD × Spock
C) 2006   ADK
As a

I want

so that
Given
And
When


Then
class MaskedRiderKabutoSpec extends Specification {
    def tendoSouji = new TendoSouji()

    def "                              "() {
      given: "                                 "
	   tendoSouji.zector = KabutoZector.getZector()
	
      and: "                       "
	   tendoSouji.attachRiderBelt()
	   	
      when: "                                      "
	   tendoSouji.setZector()
	   	
      then: "                            "
	    tendoSouji.maskedRiderType == MaskedRiderType.ARMERED_FORM
    }
}
class KabutoZector {
  	 private static KabutoZector instance = new KabutoZector()
  	 private KabutoZector() {}
  	 static def getZector() {
  	 	 return instance
                                                enum MaskedRiderType {
  	 }
                                             	 ARMERED_FORM,
  }                 class TendoSouji {
                                             	 RIDER_FORM
                    	 def zector
                                             }
class RiderBelt {   	 def riderBelt
	 def zector        	 MaskedRiderType maskedRiderType
                    	
	 boolean existZector() {
	 	 return zector?:false attachRiderBelt() {
                    	 def
	 }                 	 	 riderBelt = new RiderBelt()
	 def getMaskedArmer()} {
                    	
                    	
	 	 if(existZector()) {
                    	 def setZector() {
	 	 	 return MaskedRiderType.ARMERED_FORM
	 	 }               	 	 riderBelt.zector = this.zector
	 }                 	 	 maskedRiderType = riderBelt.getMaskedArmer()
}                   	 }
                    }
C) 2006   ADK
Spock 0.4
✤   JUnit Rules
✤   Stepwise
✤


✤


✤
JUnit Rules
  import org.junit.Rule
import org.junit.rules.*
import spock.lang.Specification

import jggug.sample.rules.*

class TimeoutRuleSpec extends Specification {
	 // JUnit Rules       Timeout
	 @Rule timeout = new Timeout(5000)
	 //     Rules       PrintLog
	 @Rule printLog = new PrintLog()
	 def "                               "() {
	 	 Thread.sleep 4999
	 	 expect: 2 == 1+1
	 }
}
Stepwise
  @Stepwise
class StepwiseExtension extends Specification {
	
	 def "                   "() {
	 	 expect: true
	 }
	
	 def "                                           "() {
	 	 expect: false
	 }

	 def "                                           "() {
	 	 expect: true
	 }
}
class OrderedInteractions extends Specification {
    def "                                  "() {
        def philip = Mock(DoubleDriver)
        def shotaro = Mock(DoubleDriver)

        when:
        philip.setGaiaMemory('        ')
        shotaro.setGaiaMemory('            ')


        then:
        1 * philip.setGaiaMemory('          ')
        then:
        1 * shotaro.setGaiaMemory('              ')
    }
}
abstract class AbstractSpec extends Specification {
    def "                        "() {
      setup: '                 ' }
    def "                        "() {
      setup: '                 ' }
}

class ConcreteSpec1 extends AbstractSpec {
  def "                         "() {
      setup: '                 ' }
    def "                        "() {
      setup: '                 ' }
}
class BlockingVariableSpec extends Specification {
	 def "                  " () {
	   	   def machine = new Machine()
	   	   def result = new BlockingVariables<WorkResult>()
	   	   machine.workDone << { r ->
	   	   result.set(r)
	   	   }

	   	   when:
	   	   machine.start()
	   	   then:
	   	   result.get() == WorkResult.OK
	   	   cleanup:
	   	   machine.shutdown()
    }
}
Spock
Grails
Grails 1.2
# grails install-plugin spock-0.4-groovy-1.6


Grails 1.3
# grails install-plugin spock-0.4-groovy-1.7
Spec
//
grails.plugin.spock.UnitSpec
//
grails.plugin.spock.ControllerSpec
// TagLib
grails.plugin.spock.TagLibSpec
//
grails.plugin.spock.IntegrationSpec
// GSP
grails.plugin.spock.GroovyPagesSpec
import grails.plugin.spock.*
class BookSpec extends UnitSpec {	
	 def "                           "() {
        setup:
        mockDomain(Book)

	   	   when:
	   	   new Book(title:title, price:price).save()
	   	
	   	   then:
	   	   Book.findByTitle(title) != null
	   	
	   	   where:
	   	   title = 'Groovy-tan in Action'
	   	   price = 6090
	   }
}
import grails.plugin.spock.*

class BookIntegrationSpec extends IntegrationSpec {
	 def bookService

	 def "                "() {
	   	   when:
	   	   bookService.registBook(title, price)
	   	
	   	   then:
	   	   Book.findByTitle(title) != null
	   	
	   	   where:
	   	   title = 'Groovy-tan in Action'
	   	   price = 6090
	   }
}
# grails test-app :spock
Grails


✓                  Spec
    Specification

✓                  .      NG
Java
Eclipse
Spock
Eclipse
Groovy
import spock.lang.Specification

class CalculatorSpecTest extends Specification {	

	 def '                  '() {
	   	   expect:
	   	   Calculator.multiply(x, y) == result
	   	
	   	   where:
	   	    x | y       | result
	   	   '2' | '3'    | 6
	   	   '-2'| '3'    | -6
	   	   '-2'| '-3'   | 6
	   	   '2' | '0'    | 0
	   }
}
Eclipse

✓               jar   OK

✓        Java
    Groovy



✓
✤   BDD
✤   Spock     Java/Groovy
    BDD
✤   Spock 0.4


✤   Grails                      GSP


✤   Eclipse     Java        Spock
Happy Spec’ing !
G*


      2010/07/24 g*workshop
     takuma.watabiki@jggug.org

G*におけるソフトウェアテスト・シーズンIII

  • 1.
    G* 2010/07/24 g*workshop takuma.watabiki@jggug.org
  • 2.
    ✤ ✤ ✤ Grails/Groovy ✤ Java ✤ twitter @bikisuke
  • 3.
  • 4.
    TDD C) TDD
  • 5.
    - BDD - C) TDD
  • 7.
  • 8.
    BDD Spock ✤ Spock 0.4 ✤ Spock
  • 9.
    BDD Spock
  • 10.
    BDD ✤ Behaviour Driven Development ✤ 2003 Dan North ✤
  • 11.
  • 12.
    As a ✤ I want ✤ so that
  • 13.
    Given ✤ When ✤ Then
  • 14.
    Spock ✤ Java Groovy BDD ✤ Java / Groovy JUnit ✤ Data Driven ✤
  • 15.
    Java 5 ✤ Groovy 1.6 or 1.7 ✤ JUnit 4.4
  • 16.
    IDE ✤ Ant, Maven, Gradle ✤ IDE Eclipse / STS, IntelliJ IDEA ✤ GAE http://meetspock.appspot.com/
  • 17.
    Hello Spock Specification import spock.lang.* class HelloSpock extends spock.lang.Specification { def cleanup() { println ' ' } def " "() { expect: name.size() == length where: name | length "Spock" | 5 } }
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
    class MaskedRiderKabutoSpec extendsSpecification { def tendoSouji = new TendoSouji() def " "() { given: " " tendoSouji.zector = KabutoZector.getZector() and: " " tendoSouji.attachRiderBelt() when: " " tendoSouji.setZector() then: " " tendoSouji.maskedRiderType == MaskedRiderType.ARMERED_FORM } }
  • 23.
    class KabutoZector { private static KabutoZector instance = new KabutoZector() private KabutoZector() {} static def getZector() { return instance enum MaskedRiderType { } ARMERED_FORM, } class TendoSouji { RIDER_FORM def zector } class RiderBelt { def riderBelt def zector MaskedRiderType maskedRiderType boolean existZector() { return zector?:false attachRiderBelt() { def } riderBelt = new RiderBelt() def getMaskedArmer()} { if(existZector()) { def setZector() { return MaskedRiderType.ARMERED_FORM } riderBelt.zector = this.zector } maskedRiderType = riderBelt.getMaskedArmer() } } }
  • 24.
  • 26.
  • 27.
    JUnit Rules ✤ Stepwise ✤ ✤ ✤
  • 28.
    JUnit Rules import org.junit.Rule import org.junit.rules.* import spock.lang.Specification import jggug.sample.rules.* class TimeoutRuleSpec extends Specification { // JUnit Rules Timeout @Rule timeout = new Timeout(5000) // Rules PrintLog @Rule printLog = new PrintLog() def " "() { Thread.sleep 4999 expect: 2 == 1+1 } }
  • 29.
    Stepwise @Stepwise classStepwiseExtension extends Specification { def " "() { expect: true } def " "() { expect: false } def " "() { expect: true } }
  • 30.
    class OrderedInteractions extendsSpecification { def " "() { def philip = Mock(DoubleDriver) def shotaro = Mock(DoubleDriver) when: philip.setGaiaMemory(' ') shotaro.setGaiaMemory(' ') then: 1 * philip.setGaiaMemory(' ') then: 1 * shotaro.setGaiaMemory(' ') } }
  • 31.
    abstract class AbstractSpecextends Specification { def " "() { setup: ' ' } def " "() { setup: ' ' } } class ConcreteSpec1 extends AbstractSpec { def " "() { setup: ' ' } def " "() { setup: ' ' } }
  • 32.
    class BlockingVariableSpec extendsSpecification { def " " () { def machine = new Machine() def result = new BlockingVariables<WorkResult>() machine.workDone << { r -> result.set(r) } when: machine.start() then: result.get() == WorkResult.OK cleanup: machine.shutdown() } }
  • 33.
  • 34.
  • 35.
    Grails 1.2 # grailsinstall-plugin spock-0.4-groovy-1.6 Grails 1.3 # grails install-plugin spock-0.4-groovy-1.7
  • 36.
  • 37.
    import grails.plugin.spock.* class BookSpecextends UnitSpec { def " "() { setup: mockDomain(Book) when: new Book(title:title, price:price).save() then: Book.findByTitle(title) != null where: title = 'Groovy-tan in Action' price = 6090 } }
  • 38.
    import grails.plugin.spock.* class BookIntegrationSpecextends IntegrationSpec { def bookService def " "() { when: bookService.registBook(title, price) then: Book.findByTitle(title) != null where: title = 'Groovy-tan in Action' price = 6090 } }
  • 39.
  • 40.
    Grails ✓ Spec Specification ✓ . NG
  • 41.
  • 42.
  • 43.
  • 45.
  • 48.
    import spock.lang.Specification class CalculatorSpecTestextends Specification { def ' '() { expect: Calculator.multiply(x, y) == result where: x | y | result '2' | '3' | 6 '-2'| '3' | -6 '-2'| '-3' | 6 '2' | '0' | 0 } }
  • 50.
    Eclipse ✓ jar OK ✓ Java Groovy ✓
  • 52.
    BDD ✤ Spock Java/Groovy BDD ✤ Spock 0.4 ✤ Grails GSP ✤ Eclipse Java Spock
  • 53.
  • 55.
    G* 2010/07/24 g*workshop takuma.watabiki@jggug.org