SlideShare une entreprise Scribd logo
1  sur  50
Smarter Testing
  With Spock

             Dmitry Voloshko
                 03/11/2012
What we’ll talk about
Spock?!

State Based Testing

Data Driven Testing

Interaction Based Testing

Spock Extensions

More Cool Stuff
Spock?!
Spock is...
A developer testing framework...

for Groovy and Java applications...

based on Groovy...

fully compatible with JUnit...

but going beyond!
Spock Can...
Reduce the lines of test code

Make tests more readable

Turn tests into specifications

Be extended in powerful ways

Bring back the fun to testing!
Getting Started
Homepage
http://spockframework.org

Source Code
https://github.com/spockframework/spock

Spock Web Console
http://meet.spockframework.org

Spock Example Project
http://downloads.spockframework.org
https://github.com/spockframework/spock/tree/groovy-1.8/spock-
example
Who’s Using Spock?
     Gradle       GPars
   Grails             Geb

  Grails Plugin Collective

     Apache Tapestry

     Griffon      Spock
            Spring?
Who’s Using Spock?
             Betfair            be2
     bemoko          BSkyB      CTI Digital
       Donewtech           Solutions
                  eHarmony
Energized Work             Gennemtænkt IT
   IntelliGrape Software             Netflix
Smarter Ecommerce          STERMEDIA Sp. z o.o.
        Software Projects Spot Diving
            SystemsForge       TouK
State Based Testing
State Based Testing
Classical Unit Testing
  Arrange
  Act
  Assert

Given-When-Then
The Code For Testing
Account.java
public class Account {
    private BigDecimal balance = new BigDecimal(0);

    public Account(BigDecimal initial) {
      balance = initial;
    }

    public BigDecimal getBalance() {
      return balance;
    }

    public void withdraw(BigDecimal amount) {
      if (amount.compareTo(BigDecimal.ZERO) < 0) {
         throw new NegativeAmountWithdrawnException(amount);
      }
      balance = balance.subtract(amount);
    }
}
The Code For Testing
NegativeAmountWithdrawnException.java


public class NegativeAmountWithdrawnException extends RuntimeException {
    private final BigDecimal amount;

    public NegativeAmountWithdrawnException(BigDecimal amount) {
      super("cannot withdraw" + amount);
      this.amount = amount;
    }

    public BigDecimal getAmount() {
      return amount;
    }
}
Show me the code
public class AccountTest {
  @Test
  public void withdrawSomeAmount() {
    // given
    Account account = new Account(BigDecimal.valueOf(5));

        // when
        account.withdraw(BigDecimal.valueOf(2));

        // then
        assertEquals(BigDecimal.valueOf(3), account.getBalance());
    }
}
Show me the code
class AccountSpec extends Specification {

    def "withdraw some amount"() {
      given:
      Account account = new Account(BigDecimal.valueOf(5));

        when:
        account.withdraw(BigDecimal.valueOf(2));

        then:
        account.getBalance() == BigDecimal.valueOf(3);
    }
}
Show me the code
class AccountSpec2 extends Specification {

    def "withdraw some amount"() {
      given:
      def account = new Account(5.0)

        when:
        account.withdraw(2.0)

        then:
        account.balance == 3.0
    }
}
Show me the code
class AccountSpec3 extends Specification {

    def "withdraw some amount"() {
      given: "an account with a balance of five euros"
      def account = new Account(5.0)

        when: "two euros are withdrawn"
        account.withdraw(2.0)

        then: "three euros remain in the account"
        account.balance == 3.0
    }
}
Show me the code
class AccountSpec4 extends Specification {
  def "can't withdraw a negative amount"() {
     given:
     def account = new Account(5.0)

        when:
        account.withdraw(-1.0)

        then:
        NegativeAmountWithdrawnException e = thrown()
        e.amount == -1.0
    }

    def "withdrawing some amount decreases the balance by exactly that amount"() {
      def account = new Account(5.0)

        when:
        account.withdraw(2.0)

        then:
        account.balance == old(account.balance) - 2.0
    }
}
Show me the code
class SharedField extends Specification {
   @Shared File file

    def "a file based test"() {
      when:
      file = new File("foo.txt")
      file.createNewFile()

        then:
        file.exists()
    }

    def "by now the object is not null"() {
      expect:
      file.exists()

        cleanup:
        file.delete()
    }
}
Show me the code
class SetupSpecSpec extends Specification {
   File file

    def setup() {
      file = new File("foo2.txt")
    }

    def "a file based test"() {
      when:
      file.createNewFile()

        then:
        file.exists()
    }

    def "by now the object is not null"() {
      expect: file.exists()
      cleanup: file.delete()
    }
}
Show me the code
class Conditions extends Specification {
  def "when-then style"() {
     when:
     def x = Math.max(5, 9)

        then:
        x == 9
    }

    def "expect style"() {
      expect:
      Math.max(5, 9) == 9
    }

    def "more complex conditions"() {
      expect:
      germanCarBrands.any { it.size() >= 3 }
    }

    private getGermanCarBrands() { ["audi", "bmw", "porsche"] }
}
Recap: State Based Testing
Blocks
setup: cleanup: expect: given: when: then:
where: and:

Fixture Methods
setup() cleanup() setupSpec() cleanupSpec()

Instance and @Shared fields

old() and thrown()
Data Driven Testing
Data Driven Testing


Test the same behavior...

with varying data!
Show me the code
class AccountSpecDataDriven extends Specification {
  @Unroll
  def "withdraw some amount"() {
     given:
     def account = new Account(balance)

        when:
        account.withdraw(withdrawn)

        then:
        account.balance == remaining

        where:
        balance | withdrawn | |remaining
        5.0     | 2.0       | | 3.0
        4.0     | 0.0       | | 4.0
        4.0     | 4.0       | | 0.0
    }
}
Show me the code
class AccountSpecDataDriven extends Specification {
  @Unroll
  def "withdrawing #withdrawn from account with balance #balance"() {
     given:
     def account = new Account(balance)

        when:
        account.withdraw(withdrawn)

        then:
        account.balance == old(account.balance) – withdrawn

        where:
        balance | withdrawn
        5.0     | 2.0
        4.0     | 0.0
        4.0     | 4.0
    }
}
Show me the code
class AccountSpecDatabaseDriven extends Specification {
  @Shared sql = Sql.newInstance("jdbc:h2:mem:", "org.h2.Driver")

    def setupSpec() {
      sql.execute("create table accountdata (id int primary key, balance decimal, withdrawn decimal, remaining decimal)")
      sql.execute("insert into accountdata values (1, 5.0, 2.0, 3.0), (2, 4.0, 0.0, 4.0), (3, 4.0, 4.0, 0.0)")
    }

    @Unroll def "withdrawing #withdrawn from account with balance #balance leaves #remaining"() {
     given:
     def account = new Account(balance)

        when:
        account.withdraw(withdrawn)

        then:
        account.balance == remaining

        where:
        [balance, withdrawn, remaining] << sql.rows("select balance, withdrawn, remaining from accountdata")
    }
}
Recap: Data Driven Testing

where: block

Data tables

External data sources

@Unroll
Interaction Based Testing
Interaction Based Testing

Design and test how your objects
communicate

Mocking frameworks to the rescue

Spock comes with its own mocking
framework
The Code For Testing
PublisherSubscriber.groovy

interface Subscriber {
    void receive(String message)
}

class Publisher {
  List<Subscriber> subscribers = []

    void publish(String message) {
      for (subscriber in subscribers) {
        try {
            subscriber.receive(message)
        } catch (ignored) {}
      }
    }
}
The Code For Testing
PublisherSubscriber.groovy
interface Subscriber2 {
    void receive(String message)
    boolean isActive()
}

class Publisher2 {
  List<Subscriber2> subscribers = []

    void publish(String message) {
      for (subscriber in subscribers) {
        try {
           if (subscriber.active) {
              subscriber.receive(message)
           }
        } catch (ignored) {}
      }
    }
}
Show me the code
class PublisherSubscriberSpec extends Specification {
  def pub = new Publisher()
  def sub1 = Mock(Subscriber)
  def sub2 = Mock(Subscriber)

    def setup() {
      pub.subscribers << sub2 << sub1
    }

    def "delivers messages to all subscribers"() {
      when:
      pub.publish("msg")

        then:
        1 * sub1.receive("msg")
        1 * sub2.receive("msg")
    }
}
Show me the code
class PublisherSubscriberSpec2 extends Specification {
  def pub = new Publisher()
  def sub1 = Mock(Subscriber)

    def setup() {
      pub.subscribers << sub1
    }

    def "delivers messages in the order they are published"() {
      when:
      pub.publish("msg1")
      pub.publish("msg2")

        then:
        1 * sub1.receive("msg1")

        then:
        1 * sub1.receive("msg2")
    }
}
Show me the code
class PublisherSubscriber2Spec extends Specification {
  def pub = new Publisher2()
  def sub1 = Mock(Subscriber2)
  def sub2 = Mock(Subscriber2)

    def setup() {
      pub.subscribers << sub1 << sub2
    }

    def "delivers messages to all active subscribers"() {
      sub1.active >> true
      sub2.active >> false

        when:
        pub.publish("msg")

        then:
        1 * sub1.receive("msg")
        0 * sub2.receive(_)
    }
}
Recap: Interaction Based Testing
  Creating
  def sub = Mock(Subscriber)
  Subscriber sub = Mock()


  Mocking
  1 * sub.receive("msg")
  (1..3) * sub.receive(_)
  (1.._) * sub.receive(_ as String)
  1 * sub.receive(!null)
  1 * sub.receive({it.contains("m")})
  1 * _./rec.*/("msg")
Recap: Interaction Based Testing
  Stubbing
  // now returns status code
  String receive(String msg) { ... }

  sub.receive(_) >> "ok"
  sub.receive(_) >>> ["ok", "ok", "fail"]
  sub.receive(_) >>> { msg -> msg.size() > 3 ? "ok" : "fail" }

  Mocking and Stubbing
  3 * sub.receive(_) >>> ["ok", "ok", "fail"]


  Impressing your friends
  (_.._) * _._(*_) >> _
Spock Extensions
Spock Extensions

Listeners

Interceptors

Annotation-driven extensions

Global extensions
Built-in Extensions
@Ignore
@IgnoreRest
@FailsWith
@Timeout
@AutoCleanup
@Stepwise
@RevertMetaClass
@Rule
Show me the code
class JUnitRules extends Specification {
  @Rule TemporaryFolder tempFolder
  @Shared File file

    def "a file based test"() {
      when:
      file = tempFolder.newFile("foo.txt")

        then:
        file.exists()
    }

    def "by now the file has been deleted"() {
      expect:
      !file.exists()
    }
}
Show me the code
@Stepwise
class StepwiseSpec extends Specification {
  def "step 1"() {
     expect: true
  }

    def "step 2"() {
      expect: true
    }

    def "step 3"() {
      expect: true
    }
}
External Extensions
spock-grails
spock-spring
spock-guice
spock-tapestry
spock-unitils


spock-griffon
spock-arquillian
spock-extensions http://github.com/robfletcher/spock-extensions
Grails Extensions
http://grails.org/plugin/spock

https://github.com/spockframework/spock-grails

grails install plugin spock 0.6

grails test-app

grails test-app unit:TestSpec
Grails Extensions
@TestFor(MouthService)
@Mock([Patient, PatientMouth, PatientTooth])
class MouthServiceSpec extends Specification {
   def "Get patient tooth by index"() {
     setup: "Create domain mocks"
        def patient = new Patient(dateOfBirth: new Date('05/03/1984')).save(false)
        def patientTooth = new PatientTooth(index: 10, toothCode: "10").save(false)
        def patientMouth = new PatientMouth(patient: patient, patientTeeth: [patientTooth]).save(false)

        when:
         patientTooth = service.getPatientToothByIndex(patientMouth, index)

        then:
          patientTooth.toothCode == tooth
          patientMouth.patientTeeth.contains(patientTooth)

        where:
          index | tooth
          10 | "10"
          20 | null
    }
}
Spring Extension
class InjectionExamples extends Specification {
   @Autowired
   Service1 byType

    @Resource
    Service1 byName

    @Autowired
    ApplicationContext context
}
Other Cool Stuff
Configuring Spock
~/.spock/SpockConfig.groovy, or on class path, or with -Dspock.configuration

runner {
    filterStackTrace false
    include Fast
    exclude Slow
    optimizeRunOrder true
}

@Fast
class MyFastSpec extends Specification {
     def "I’m fast as hell!"() { expect: true }

    @Slow
    def “Sorry, can’t keep up..."() {expect: false }
}
Tooling

Eclipse, IDEA

Ant, Maven, Gradle

Jenkins, Bamboo, TeamCity

Spock runs everywhere JUnit and Groovy run!
Spock Under The Hood
You write...
a = 1; b = 2; c = 4
expect: sum(a, b) == c


Spock generates...
def rec = new ValueRecorder()
verifier.expect(
  rec.record(rec.record(sum(rec.record(a),
              rec.record(b)) == rec.record(c)))

 You see...
  sum (a, b) == c
  |    | | | |
  3    12 | 4
            false
Q&A
Homepage
http://spockframework.org


Source Code
https://github.com/spockframework/spock


Spock Web Console
http://meet.spockframework.org


Spock Example Project
http://downloads.spockframework.org
https://github.com/spockframework/spock/tree/groovy-1.8/spock-example

Contenu connexe

Tendances

Grails/Groovyによる開発事例紹介
Grails/Groovyによる開発事例紹介Grails/Groovyによる開発事例紹介
Grails/Groovyによる開発事例紹介Kiyotaka Oku
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent codeDror Helper
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lispelliando dias
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctlyDror Helper
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeletonIram Ramrajkar
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYCMike Dirolf
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Roy Yu
 

Tendances (20)

Grails/Groovyによる開発事例紹介
Grails/Groovyによる開発事例紹介Grails/Groovyによる開発事例紹介
Grails/Groovyによる開発事例紹介
 
Ggug spock
Ggug spockGgug spock
Ggug spock
 
Celery
CeleryCelery
Celery
 
Spock Framework
Spock FrameworkSpock Framework
Spock Framework
 
Spock
SpockSpock
Spock
 
DCN Practical
DCN PracticalDCN Practical
DCN Practical
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent code
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Spock
SpockSpock
Spock
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
Ad java prac sol set
Ad java prac sol setAd java prac sol set
Ad java prac sol set
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
Unit testing
Unit testingUnit testing
Unit testing
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 

En vedette

Taming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and GebTaming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and GebC4Media
 
Java Testing With Spock - Ken Sipe (Trexin Consulting)
Java Testing With Spock - Ken Sipe (Trexin Consulting)Java Testing With Spock - Ken Sipe (Trexin Consulting)
Java Testing With Spock - Ken Sipe (Trexin Consulting)jaxLondonConference
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spockGR8Conf
 
Westrich spock-assets-gum
Westrich spock-assets-gumWestrich spock-assets-gum
Westrich spock-assets-gumBrian Westrich
 
Spock - the next stage of unit testing
Spock - the next stage of unit testingSpock - the next stage of unit testing
Spock - the next stage of unit testingjugkaraganda
 
Vert.x 세미나 이지원_배포용
Vert.x 세미나 이지원_배포용Vert.x 세미나 이지원_배포용
Vert.x 세미나 이지원_배포용지원 이
 
SeConf2015: Advanced Automated Visual Testing With Selenium
SeConf2015: Advanced Automated Visual Testing With SeleniumSeConf2015: Advanced Automated Visual Testing With Selenium
SeConf2015: Advanced Automated Visual Testing With Seleniumadamcarmi
 
Spring Cloud Contract And Your Microservice Architecture
Spring Cloud Contract And Your Microservice ArchitectureSpring Cloud Contract And Your Microservice Architecture
Spring Cloud Contract And Your Microservice ArchitectureMarcin Grzejszczak
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with SpockAlexander Tarlinder
 
Fabulous Tests on Spock and Groovy
Fabulous Tests on Spock and GroovyFabulous Tests on Spock and Groovy
Fabulous Tests on Spock and GroovyYaroslav Pernerovsky
 
Spock Extensions Anatomy
Spock Extensions AnatomySpock Extensions Anatomy
Spock Extensions AnatomyEvgeny Goldin
 
Spring cloud for microservices architecture
Spring cloud for microservices architectureSpring cloud for microservices architecture
Spring cloud for microservices architectureIgor Khotin
 
Consumer Driven Contracts and Your Microservice Architecture
Consumer Driven Contracts and Your Microservice ArchitectureConsumer Driven Contracts and Your Microservice Architecture
Consumer Driven Contracts and Your Microservice ArchitectureMarcin Grzejszczak
 

En vedette (18)

Geb with spock
Geb with spockGeb with spock
Geb with spock
 
Taming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and GebTaming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and Geb
 
Java Testing With Spock - Ken Sipe (Trexin Consulting)
Java Testing With Spock - Ken Sipe (Trexin Consulting)Java Testing With Spock - Ken Sipe (Trexin Consulting)
Java Testing With Spock - Ken Sipe (Trexin Consulting)
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
Codemotion 2015 spock_workshop
Codemotion 2015 spock_workshopCodemotion 2015 spock_workshop
Codemotion 2015 spock_workshop
 
Westrich spock-assets-gum
Westrich spock-assets-gumWestrich spock-assets-gum
Westrich spock-assets-gum
 
Spock - the next stage of unit testing
Spock - the next stage of unit testingSpock - the next stage of unit testing
Spock - the next stage of unit testing
 
TDD with Spock @xpdays_ua
TDD with Spock @xpdays_uaTDD with Spock @xpdays_ua
TDD with Spock @xpdays_ua
 
Spring puzzlers
Spring puzzlersSpring puzzlers
Spring puzzlers
 
Unit test-using-spock in Grails
Unit test-using-spock in GrailsUnit test-using-spock in Grails
Unit test-using-spock in Grails
 
Vert.x 세미나 이지원_배포용
Vert.x 세미나 이지원_배포용Vert.x 세미나 이지원_배포용
Vert.x 세미나 이지원_배포용
 
SeConf2015: Advanced Automated Visual Testing With Selenium
SeConf2015: Advanced Automated Visual Testing With SeleniumSeConf2015: Advanced Automated Visual Testing With Selenium
SeConf2015: Advanced Automated Visual Testing With Selenium
 
Spring Cloud Contract And Your Microservice Architecture
Spring Cloud Contract And Your Microservice ArchitectureSpring Cloud Contract And Your Microservice Architecture
Spring Cloud Contract And Your Microservice Architecture
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
 
Fabulous Tests on Spock and Groovy
Fabulous Tests on Spock and GroovyFabulous Tests on Spock and Groovy
Fabulous Tests on Spock and Groovy
 
Spock Extensions Anatomy
Spock Extensions AnatomySpock Extensions Anatomy
Spock Extensions Anatomy
 
Spring cloud for microservices architecture
Spring cloud for microservices architectureSpring cloud for microservices architecture
Spring cloud for microservices architecture
 
Consumer Driven Contracts and Your Microservice Architecture
Consumer Driven Contracts and Your Microservice ArchitectureConsumer Driven Contracts and Your Microservice Architecture
Consumer Driven Contracts and Your Microservice Architecture
 

Similaire à Smarter Testing With Spock

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
BDD - Behavior Driven Development Webapps mit Groovy Spock und GebBDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
BDD - Behavior Driven Development Webapps mit Groovy Spock und GebChristian Baranowski
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門Tsuyoshi Yamamoto
 
Testowanie JavaScript
Testowanie JavaScriptTestowanie JavaScript
Testowanie JavaScriptTomasz Bak
 
Spock the enterprise ready specifiation framework - Ted Vinke
Spock the enterprise ready specifiation framework - Ted VinkeSpock the enterprise ready specifiation framework - Ted Vinke
Spock the enterprise ready specifiation framework - Ted VinkeTed Vinke
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6Richard Jones
 
Introduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-finalIntroduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-finalM Malai
 
Introduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerIntroduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerMydbops
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Javascript variables and datatypes
Javascript variables and datatypesJavascript variables and datatypes
Javascript variables and datatypesVarun C M
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkIndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayNatasha Murashev
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用Felinx Lee
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in AngularYadong Xie
 

Similaire à Smarter Testing With Spock (20)

BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
BDD - Behavior Driven Development Webapps mit Groovy Spock und GebBDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Testowanie JavaScript
Testowanie JavaScriptTestowanie JavaScript
Testowanie JavaScript
 
Spock the enterprise ready specifiation framework - Ted Vinke
Spock the enterprise ready specifiation framework - Ted VinkeSpock the enterprise ready specifiation framework - Ted Vinke
Spock the enterprise ready specifiation framework - Ted Vinke
 
Kitura Todolist tutorial
Kitura Todolist tutorialKitura Todolist tutorial
Kitura Todolist tutorial
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6
 
Introduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-finalIntroduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-final
 
Introduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerIntroduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizer
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Solid scala
Solid scalaSolid scala
Solid scala
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Javascript variables and datatypes
Javascript variables and datatypesJavascript variables and datatypes
Javascript variables and datatypes
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
Funcitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional WayFuncitonal Swift Conference: The Functional Way
Funcitonal Swift Conference: The Functional Way
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in Angular
 

Plus de IT Weekend

Quality attributes testing. From Architecture to test acceptance
Quality attributes testing. From Architecture to test acceptanceQuality attributes testing. From Architecture to test acceptance
Quality attributes testing. From Architecture to test acceptanceIT Weekend
 
Mobile development for JavaScript developer
Mobile development for JavaScript developerMobile development for JavaScript developer
Mobile development for JavaScript developerIT Weekend
 
Building an Innovation & Strategy Process
Building an Innovation & Strategy ProcessBuilding an Innovation & Strategy Process
Building an Innovation & Strategy ProcessIT Weekend
 
IT Professionals – The Right Time/The Right Place
IT Professionals – The Right Time/The Right PlaceIT Professionals – The Right Time/The Right Place
IT Professionals – The Right Time/The Right PlaceIT Weekend
 
Building a Data Driven Organization
Building a Data Driven OrganizationBuilding a Data Driven Organization
Building a Data Driven OrganizationIT Weekend
 
7 Tools for the Product Owner
7 Tools for the Product Owner 7 Tools for the Product Owner
7 Tools for the Product Owner IT Weekend
 
Hacking your Doorbell
Hacking your DoorbellHacking your Doorbell
Hacking your DoorbellIT Weekend
 
An era of possibilities, a window in time
An era of possibilities, a window in timeAn era of possibilities, a window in time
An era of possibilities, a window in timeIT Weekend
 
Web services automation from sketch
Web services automation from sketchWeb services automation from sketch
Web services automation from sketchIT Weekend
 
REST that won't make you cry
REST that won't make you cryREST that won't make you cry
REST that won't make you cryIT Weekend
 
Как договариваться с начальником и заказчиком: выбираем нужный протокол общения
Как договариваться с начальником и заказчиком: выбираем нужный протокол общенияКак договариваться с начальником и заказчиком: выбираем нужный протокол общения
Как договариваться с начальником и заказчиком: выбираем нужный протокол общенияIT Weekend
 
Обзор программы SAP HANA Startup Focus
Обзор программы SAP HANA Startup FocusОбзор программы SAP HANA Startup Focus
Обзор программы SAP HANA Startup FocusIT Weekend
 
World of Agile: Kanban
World of Agile: KanbanWorld of Agile: Kanban
World of Agile: KanbanIT Weekend
 
Risk Management
Risk ManagementRisk Management
Risk ManagementIT Weekend
 
«Spring Integration as Integration Patterns Provider»
«Spring Integration as Integration Patterns Provider»«Spring Integration as Integration Patterns Provider»
«Spring Integration as Integration Patterns Provider»IT Weekend
 
Cutting edge of Machine Learning
Cutting edge of Machine LearningCutting edge of Machine Learning
Cutting edge of Machine LearningIT Weekend
 
Parallel Programming In Modern World .NET Technics
Parallel Programming In Modern World .NET TechnicsParallel Programming In Modern World .NET Technics
Parallel Programming In Modern World .NET TechnicsIT Weekend
 
Parallel programming in modern world .net technics shared
Parallel programming in modern world .net technics   sharedParallel programming in modern world .net technics   shared
Parallel programming in modern world .net technics sharedIT Weekend
 
Maximize Effectiveness of Human Capital
Maximize Effectiveness of Human CapitalMaximize Effectiveness of Human Capital
Maximize Effectiveness of Human CapitalIT Weekend
 

Plus de IT Weekend (20)

Quality attributes testing. From Architecture to test acceptance
Quality attributes testing. From Architecture to test acceptanceQuality attributes testing. From Architecture to test acceptance
Quality attributes testing. From Architecture to test acceptance
 
Mobile development for JavaScript developer
Mobile development for JavaScript developerMobile development for JavaScript developer
Mobile development for JavaScript developer
 
Building an Innovation & Strategy Process
Building an Innovation & Strategy ProcessBuilding an Innovation & Strategy Process
Building an Innovation & Strategy Process
 
IT Professionals – The Right Time/The Right Place
IT Professionals – The Right Time/The Right PlaceIT Professionals – The Right Time/The Right Place
IT Professionals – The Right Time/The Right Place
 
Building a Data Driven Organization
Building a Data Driven OrganizationBuilding a Data Driven Organization
Building a Data Driven Organization
 
7 Tools for the Product Owner
7 Tools for the Product Owner 7 Tools for the Product Owner
7 Tools for the Product Owner
 
Hacking your Doorbell
Hacking your DoorbellHacking your Doorbell
Hacking your Doorbell
 
An era of possibilities, a window in time
An era of possibilities, a window in timeAn era of possibilities, a window in time
An era of possibilities, a window in time
 
Web services automation from sketch
Web services automation from sketchWeb services automation from sketch
Web services automation from sketch
 
Why Ruby?
Why Ruby? Why Ruby?
Why Ruby?
 
REST that won't make you cry
REST that won't make you cryREST that won't make you cry
REST that won't make you cry
 
Как договариваться с начальником и заказчиком: выбираем нужный протокол общения
Как договариваться с начальником и заказчиком: выбираем нужный протокол общенияКак договариваться с начальником и заказчиком: выбираем нужный протокол общения
Как договариваться с начальником и заказчиком: выбираем нужный протокол общения
 
Обзор программы SAP HANA Startup Focus
Обзор программы SAP HANA Startup FocusОбзор программы SAP HANA Startup Focus
Обзор программы SAP HANA Startup Focus
 
World of Agile: Kanban
World of Agile: KanbanWorld of Agile: Kanban
World of Agile: Kanban
 
Risk Management
Risk ManagementRisk Management
Risk Management
 
«Spring Integration as Integration Patterns Provider»
«Spring Integration as Integration Patterns Provider»«Spring Integration as Integration Patterns Provider»
«Spring Integration as Integration Patterns Provider»
 
Cutting edge of Machine Learning
Cutting edge of Machine LearningCutting edge of Machine Learning
Cutting edge of Machine Learning
 
Parallel Programming In Modern World .NET Technics
Parallel Programming In Modern World .NET TechnicsParallel Programming In Modern World .NET Technics
Parallel Programming In Modern World .NET Technics
 
Parallel programming in modern world .net technics shared
Parallel programming in modern world .net technics   sharedParallel programming in modern world .net technics   shared
Parallel programming in modern world .net technics shared
 
Maximize Effectiveness of Human Capital
Maximize Effectiveness of Human CapitalMaximize Effectiveness of Human Capital
Maximize Effectiveness of Human Capital
 

Smarter Testing With Spock

  • 1. Smarter Testing With Spock Dmitry Voloshko 03/11/2012
  • 2. What we’ll talk about Spock?! State Based Testing Data Driven Testing Interaction Based Testing Spock Extensions More Cool Stuff
  • 4. Spock is... A developer testing framework... for Groovy and Java applications... based on Groovy... fully compatible with JUnit... but going beyond!
  • 5. Spock Can... Reduce the lines of test code Make tests more readable Turn tests into specifications Be extended in powerful ways Bring back the fun to testing!
  • 6. Getting Started Homepage http://spockframework.org Source Code https://github.com/spockframework/spock Spock Web Console http://meet.spockframework.org Spock Example Project http://downloads.spockframework.org https://github.com/spockframework/spock/tree/groovy-1.8/spock- example
  • 7. Who’s Using Spock? Gradle GPars Grails Geb Grails Plugin Collective Apache Tapestry Griffon Spock Spring?
  • 8. Who’s Using Spock? Betfair be2 bemoko BSkyB CTI Digital Donewtech Solutions eHarmony Energized Work Gennemtænkt IT IntelliGrape Software Netflix Smarter Ecommerce STERMEDIA Sp. z o.o. Software Projects Spot Diving SystemsForge TouK
  • 10. State Based Testing Classical Unit Testing Arrange Act Assert Given-When-Then
  • 11. The Code For Testing Account.java public class Account { private BigDecimal balance = new BigDecimal(0); public Account(BigDecimal initial) { balance = initial; } public BigDecimal getBalance() { return balance; } public void withdraw(BigDecimal amount) { if (amount.compareTo(BigDecimal.ZERO) < 0) { throw new NegativeAmountWithdrawnException(amount); } balance = balance.subtract(amount); } }
  • 12. The Code For Testing NegativeAmountWithdrawnException.java public class NegativeAmountWithdrawnException extends RuntimeException { private final BigDecimal amount; public NegativeAmountWithdrawnException(BigDecimal amount) { super("cannot withdraw" + amount); this.amount = amount; } public BigDecimal getAmount() { return amount; } }
  • 13. Show me the code public class AccountTest { @Test public void withdrawSomeAmount() { // given Account account = new Account(BigDecimal.valueOf(5)); // when account.withdraw(BigDecimal.valueOf(2)); // then assertEquals(BigDecimal.valueOf(3), account.getBalance()); } }
  • 14. Show me the code class AccountSpec extends Specification { def "withdraw some amount"() { given: Account account = new Account(BigDecimal.valueOf(5)); when: account.withdraw(BigDecimal.valueOf(2)); then: account.getBalance() == BigDecimal.valueOf(3); } }
  • 15. Show me the code class AccountSpec2 extends Specification { def "withdraw some amount"() { given: def account = new Account(5.0) when: account.withdraw(2.0) then: account.balance == 3.0 } }
  • 16. Show me the code class AccountSpec3 extends Specification { def "withdraw some amount"() { given: "an account with a balance of five euros" def account = new Account(5.0) when: "two euros are withdrawn" account.withdraw(2.0) then: "three euros remain in the account" account.balance == 3.0 } }
  • 17. Show me the code class AccountSpec4 extends Specification { def "can't withdraw a negative amount"() { given: def account = new Account(5.0) when: account.withdraw(-1.0) then: NegativeAmountWithdrawnException e = thrown() e.amount == -1.0 } def "withdrawing some amount decreases the balance by exactly that amount"() { def account = new Account(5.0) when: account.withdraw(2.0) then: account.balance == old(account.balance) - 2.0 } }
  • 18. Show me the code class SharedField extends Specification { @Shared File file def "a file based test"() { when: file = new File("foo.txt") file.createNewFile() then: file.exists() } def "by now the object is not null"() { expect: file.exists() cleanup: file.delete() } }
  • 19. Show me the code class SetupSpecSpec extends Specification { File file def setup() { file = new File("foo2.txt") } def "a file based test"() { when: file.createNewFile() then: file.exists() } def "by now the object is not null"() { expect: file.exists() cleanup: file.delete() } }
  • 20. Show me the code class Conditions extends Specification { def "when-then style"() { when: def x = Math.max(5, 9) then: x == 9 } def "expect style"() { expect: Math.max(5, 9) == 9 } def "more complex conditions"() { expect: germanCarBrands.any { it.size() >= 3 } } private getGermanCarBrands() { ["audi", "bmw", "porsche"] } }
  • 21. Recap: State Based Testing Blocks setup: cleanup: expect: given: when: then: where: and: Fixture Methods setup() cleanup() setupSpec() cleanupSpec() Instance and @Shared fields old() and thrown()
  • 23. Data Driven Testing Test the same behavior... with varying data!
  • 24. Show me the code class AccountSpecDataDriven extends Specification { @Unroll def "withdraw some amount"() { given: def account = new Account(balance) when: account.withdraw(withdrawn) then: account.balance == remaining where: balance | withdrawn | |remaining 5.0 | 2.0 | | 3.0 4.0 | 0.0 | | 4.0 4.0 | 4.0 | | 0.0 } }
  • 25. Show me the code class AccountSpecDataDriven extends Specification { @Unroll def "withdrawing #withdrawn from account with balance #balance"() { given: def account = new Account(balance) when: account.withdraw(withdrawn) then: account.balance == old(account.balance) – withdrawn where: balance | withdrawn 5.0 | 2.0 4.0 | 0.0 4.0 | 4.0 } }
  • 26. Show me the code class AccountSpecDatabaseDriven extends Specification { @Shared sql = Sql.newInstance("jdbc:h2:mem:", "org.h2.Driver") def setupSpec() { sql.execute("create table accountdata (id int primary key, balance decimal, withdrawn decimal, remaining decimal)") sql.execute("insert into accountdata values (1, 5.0, 2.0, 3.0), (2, 4.0, 0.0, 4.0), (3, 4.0, 4.0, 0.0)") } @Unroll def "withdrawing #withdrawn from account with balance #balance leaves #remaining"() { given: def account = new Account(balance) when: account.withdraw(withdrawn) then: account.balance == remaining where: [balance, withdrawn, remaining] << sql.rows("select balance, withdrawn, remaining from accountdata") } }
  • 27. Recap: Data Driven Testing where: block Data tables External data sources @Unroll
  • 29. Interaction Based Testing Design and test how your objects communicate Mocking frameworks to the rescue Spock comes with its own mocking framework
  • 30. The Code For Testing PublisherSubscriber.groovy interface Subscriber { void receive(String message) } class Publisher { List<Subscriber> subscribers = [] void publish(String message) { for (subscriber in subscribers) { try { subscriber.receive(message) } catch (ignored) {} } } }
  • 31. The Code For Testing PublisherSubscriber.groovy interface Subscriber2 { void receive(String message) boolean isActive() } class Publisher2 { List<Subscriber2> subscribers = [] void publish(String message) { for (subscriber in subscribers) { try { if (subscriber.active) { subscriber.receive(message) } } catch (ignored) {} } } }
  • 32. Show me the code class PublisherSubscriberSpec extends Specification { def pub = new Publisher() def sub1 = Mock(Subscriber) def sub2 = Mock(Subscriber) def setup() { pub.subscribers << sub2 << sub1 } def "delivers messages to all subscribers"() { when: pub.publish("msg") then: 1 * sub1.receive("msg") 1 * sub2.receive("msg") } }
  • 33. Show me the code class PublisherSubscriberSpec2 extends Specification { def pub = new Publisher() def sub1 = Mock(Subscriber) def setup() { pub.subscribers << sub1 } def "delivers messages in the order they are published"() { when: pub.publish("msg1") pub.publish("msg2") then: 1 * sub1.receive("msg1") then: 1 * sub1.receive("msg2") } }
  • 34. Show me the code class PublisherSubscriber2Spec extends Specification { def pub = new Publisher2() def sub1 = Mock(Subscriber2) def sub2 = Mock(Subscriber2) def setup() { pub.subscribers << sub1 << sub2 } def "delivers messages to all active subscribers"() { sub1.active >> true sub2.active >> false when: pub.publish("msg") then: 1 * sub1.receive("msg") 0 * sub2.receive(_) } }
  • 35. Recap: Interaction Based Testing Creating def sub = Mock(Subscriber) Subscriber sub = Mock() Mocking 1 * sub.receive("msg") (1..3) * sub.receive(_) (1.._) * sub.receive(_ as String) 1 * sub.receive(!null) 1 * sub.receive({it.contains("m")}) 1 * _./rec.*/("msg")
  • 36. Recap: Interaction Based Testing Stubbing // now returns status code String receive(String msg) { ... } sub.receive(_) >> "ok" sub.receive(_) >>> ["ok", "ok", "fail"] sub.receive(_) >>> { msg -> msg.size() > 3 ? "ok" : "fail" } Mocking and Stubbing 3 * sub.receive(_) >>> ["ok", "ok", "fail"] Impressing your friends (_.._) * _._(*_) >> _
  • 40. Show me the code class JUnitRules extends Specification { @Rule TemporaryFolder tempFolder @Shared File file def "a file based test"() { when: file = tempFolder.newFile("foo.txt") then: file.exists() } def "by now the file has been deleted"() { expect: !file.exists() } }
  • 41. Show me the code @Stepwise class StepwiseSpec extends Specification { def "step 1"() { expect: true } def "step 2"() { expect: true } def "step 3"() { expect: true } }
  • 44. Grails Extensions @TestFor(MouthService) @Mock([Patient, PatientMouth, PatientTooth]) class MouthServiceSpec extends Specification { def "Get patient tooth by index"() { setup: "Create domain mocks" def patient = new Patient(dateOfBirth: new Date('05/03/1984')).save(false) def patientTooth = new PatientTooth(index: 10, toothCode: "10").save(false) def patientMouth = new PatientMouth(patient: patient, patientTeeth: [patientTooth]).save(false) when: patientTooth = service.getPatientToothByIndex(patientMouth, index) then: patientTooth.toothCode == tooth patientMouth.patientTeeth.contains(patientTooth) where: index | tooth 10 | "10" 20 | null } }
  • 45. Spring Extension class InjectionExamples extends Specification { @Autowired Service1 byType @Resource Service1 byName @Autowired ApplicationContext context }
  • 47. Configuring Spock ~/.spock/SpockConfig.groovy, or on class path, or with -Dspock.configuration runner { filterStackTrace false include Fast exclude Slow optimizeRunOrder true } @Fast class MyFastSpec extends Specification { def "I’m fast as hell!"() { expect: true } @Slow def “Sorry, can’t keep up..."() {expect: false } }
  • 48. Tooling Eclipse, IDEA Ant, Maven, Gradle Jenkins, Bamboo, TeamCity Spock runs everywhere JUnit and Groovy run!
  • 49. Spock Under The Hood You write... a = 1; b = 2; c = 4 expect: sum(a, b) == c Spock generates... def rec = new ValueRecorder() verifier.expect( rec.record(rec.record(sum(rec.record(a), rec.record(b)) == rec.record(c))) You see... sum (a, b) == c | | | | | 3 12 | 4 false
  • 50. Q&A Homepage http://spockframework.org Source Code https://github.com/spockframework/spock Spock Web Console http://meet.spockframework.org Spock Example Project http://downloads.spockframework.org https://github.com/spockframework/spock/tree/groovy-1.8/spock-example