Spock: Test Well and Prosper
-
Upload
ken-kousen -
Category
Documents
-
view
2.276 -
download
6
description
Transcript of Spock: Test Well and Prosper
SpockI have been, and always shall be, your
friendly testing framework
Ken KousenKousen IT, Inc.http://[email protected]@kenkousen
Making Java Groovyhttp://manning.com/kousen
Who Am I?
Testing frameworkWritten in Groovy
A logical framework for enterprise testing
Combination ofSpecification + Mock
What is Spock?
Spock home pagehttp://spockframework.org
redirects to http://code.google.com/p/spock
Githubhttps://github.com/spockframework/spock
The Search for Spock
Extend spock.lang.Specification
class MySpec extends Specification
Create a Spock test
Demo: Palindrome Checker
Simple Specification
def setup() {} run before every feature method
def cleanup() {} run after every feature method
def setupSpec() {} run before first feature method
def cleanupSpec() {} run after last feature method
Like JUnit 4: @Before, @After, @BeforeClass, @AfterClass
Fixture Methods
Test methodsdef "descriptive name"() {
// blocks}
Feature Methods
setup: cleanup:given:
when:Stimulus
then:Response, booleans are checked
expect: where:
Blocks
when:Contents are arbitrary
then:conditionsexceptionsinteractions (mocks described below)
Always occur together
when: and then:
Sweet method in Specification class
expression value beforewhere block
when: obj.count()then:count == old(count) + 1
old Method what they thought old Kirk would look like
what he actually looks like
Annotation for shared objectsNote: instance fields are not shared
@Shared res = new VeryExpensiveResource()
@Shared sql = Sql.newInstance(...)
@Shared
Demo: Library Computer
@Shared
thrown() and notThrown()
then:thrown(SqlException)
-- or --SqlException e = thrown()e.sqlCode == ...
Can do work after catching exception
Exceptions are exceptions evil or just goatees?
Tests that iterate through dataUse where: clause
expect: name.size() == length
where:[name,length] << [['Kirk',4],['Spock',5]]
Parameterized feature methods
where: clause supports data tables
expect: name.size() == lengthwhere: name | length 'Kirk' | 4'Spock' | 5'McCoy' | 5
Data Table
Shouldn't Data run on Android?
Supports anything Groovy can iterate over
expect: x + y == zwhere:[x,y,z] << sql.rows('select x,y,z from ...')
where: clause
Display separate messagefor each row of data
Spock 0.5: @Unroll({"...$var..."})
Spock 0.6+:@Unrolldef "my test #var ..."() { ... }
@Unroll
Demos:Hello, Spock!DataDrivenDatabaseDrivenStadiumLocationsSpec
Data Specs
Working with Mock objects
Interactions
interaction
NO KILL I
Two syntax options:def items = Mock(List)
List items = Mock()
Can mock interfaces with standard libsMock classes with CGLIB
Creating Mocks
Setting Expectations
Use >> operatorlist.get(0) >> 'data'
Global:Defined outside then: blockValid to end of feature method
Local:Defined inside then: blockValid inside preceding when: block
Global vs Local
No cardinalityMust have return value
then:list.get(0) >> 'data'
Optional
Must have cardinalityMay have return value
then:1 * list.get(0) >> 'data'
then:3 * list.size()
Required
Ranges with wildcardWildcard is _ (underscore)
3 * list.size() // 3 times(3.._) * list.size() // 3 or more(_..3) * list.size() // up to 3
Cardinalities
RegexAny set method with one argpojo./set.*/(_)
Nulls, not nullpojo.method(!null)
All sorts of constraints
as Operatordir.listFiles(_ as FileFilter)
Closurescount.increment { it ==~ /a*b/ }
All sorts of constraints
Use multiple then blocks
def 'testing order of methods'() {when: obj.method()
then: 1*collaborator.method1()then: 1*collaborator.method2()
}
Testing Invocation Order
Interactions
Demos:PublisherSubscriberTribbleSpec
@Timeout
@Ignore
@IgnoreRest
@FailsWith
Extensions
Test fails with expected exception
@FailsWith(TooFewInvocationsError)def "required interaction"() {
def m = Mock(List)2 * m.get(_) >> "foo"expect: m.get(3) == "foo"
}
@FailsWith
Parametersvalue=ExpectedExceptionOrErrorreason="reason for failure"
@FailsWith
@IgnoreDon't run a particular test or test classOptional value = reason
@IgnoreRestDon't run any OTHER tests
@Ignore and @IgnoreRest
Method in Specification classTakes closure argument
def 'use interaction block'() {when: obj.method()then:interaction {
// do whatever}
}
interaction block
BDD
Behavior Driven DevelopmentEach block accepts string descriptionJust documentation
def "number of tribbles in storage compartment"() {
given: "average litter of 10"
and: "new generation every 12 hours over a period of three days"
when: "tribbles get into storage compartments"
then: "compute number of tribbles"
}
Like most modern open source projects
Documentation can be thin or outdated
Tests are excellent
See "smoke" tests in source
Spock's Own Tests
http://github.com/spockframework/spockhttp://code.google.com/p/spockhttp://spockframework.orghttp://meet.spockframework.orghttp://groups.google.com/group/spockframework?pli=1
Source code for examples is from1. spock-example project
https://github.com/spockframework/spock-example2. my GitHub repo
https://github.com/kousen/Spock-NFJS-Article
Links
Please complete your session evals
Session Evals