spock: boldly go where no test has gone before - devoxx12
DESCRIPTION
TRANSCRIPT
Spock:���Boldly go where no test has
gone before
Andres Almiray Canoo Fellow
Canoo Engineering AG
@aalmiray
3
Andres Almiray
Speaker Bio
■ Java developer since the beginning
■ True believer in open source
■ Groovy committer since 2007
■ Project lead of the Griffon framework
■ Currently working for
What is Spock?
Where, Who, How?
■ http://spockframework.org
■ Peter Niederwiser @pniederw
■ Groovy based Testing Language
■ Byte code manipulation at compile time
■ Inspired by JUnit, Rspec, jMock, Mockito, Groovy, Scala and Vulcans
4
Why?
■ Expressive testing language
■ Easy to learn
■ Usable from unit to end-to-end level
■ Leverages Groovy language features
■ Runs with JUnit: compatible with IDEs, build tools & CI
■ Extensible for specialized testing scenarios
5
First Cut class HelloSpock extends spock.lang.Specification { def "length of Spock's and his friends' names"() { expect: name.size() == length where: name | length "Spock" | 5 "Kirk" | 4 "Scotty" | 6 } }
6
Introducing a bug class HelloSpock extends spock.lang.Specification { def "length of Spock's and his friends' names"() { expect: name.size() == length where: name | length "Spock" | 5 "Kirk" | 4 "Scotty" | 7 } }
7
A wild error appears! Condition not satisfied:
name.size() == length
| | | |
| 6 | 7
Scotty false
at com.acme.HelloSpock.length of Spock's and his friends' names(HelloSpock.groovy:6)
Feature List (1)
Blocks
■ given: preconditions, data fixtures, etc.
■ when: actions that trigger some outcome
■ then: makes assertions about outcome
■ expect: short alternative to when & then
■ where: applies varied inputs
■ and: sub-divides other blocks
■ setup: alias for given
■ cleanup: post-conditions, housekeeping, etc.
8
Feature List (2)
Lifecycle
■ setup
■ cleanup
■ setupSpec
■ cleanupSpec
9
Data Driven
■ List based variables
■ Table based variables
■ @Unroll
■ @Shared
10
Unrolling class HelloSpock extends spock.lang.Specification {
@Unroll
def "Length of #name should be #name.size(), actual value is #length"() { expect: name.size() == length where: name | length "Spock" | 5 "Kirk" | 4 "Scotty" | 6 } }
Unrolling as seen by an IDE
11
12
Interactions (Mocks) class BindableSpec extends Specification {
def "Model properties are observable"() {
given:
def model = new Model()
def listener = Mock(PropertyChangeListener)
when:
model.addPropertyChangeListener(listener)
model.name = 'Groovy'
model.name = 'Java'
then:
1 * listener.propertyChange({it.newValue == 'Groovy'})
1 * listener.propertyChange({it.newValue == 'Java'})
}
}
But wait, there’s more!
■ http://docs.spockframework.org/en/latest/
■ Spock is extensible via plugins
■ Functional web testing with GEB
■ Plugins exist for Grails and Griffon
■ Next release will be 1.0
13
Q&A Andres Almiray
@aalmiray