Contact Info...Groovy Programming Fundamentals Practical Groovy Programming Mastering Groovy...

Preview:

Citation preview

SpockI have been, and always shall be, your

friendly testing framework

Contact Info

Ken KousenKousen IT, Inc.ken.kousen@kousenit.comhttp://www.kousenit.comhttp://kousenit.wordpress.com (blog)@kenkousen

Publications

O'Reilly video courses: (See http://shop.oreilly.com for details)Groovy Programming FundamentalsPractical Groovy ProgrammingMastering Groovy ProgrammingLearning AndroidPractical AndroidGradle FundamentalsGradle for AndroidSpring Framework EssentialsAdvanced Java Development

Testing frameworkWritten in Groovy and Java

What is Spock?

Testing frameworkWritten in Groovy and Java

A logical framework for enterprise testing

What is Spock?

Testing frameworkWritten in Groovy

A logical framework for enterprise testing

Combination ofSpecification + Mock

What is Spock?

Spock home pagehttp://spockframework.org

has links to:

Githubhttps://github.com/spockframework/spock

Docshttps://docs.spockframework.org

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

Fixture Methods

Spock JUnit ------------------- -----------------------

setup setUp, @Before

cleanup tearDown, @After

setupSpec @BeforeClass

cleanupSpec @AfterClass

Fixture Methods

Test methodsdef "descriptive name"() {

// blocks

}

Feature Methods

setup: cleanup:given:

Syntactic sugar

Anything before when: or expect:

Blocks

setup: cleanup:given:

when:Stimulus

then:Response, booleans are checked

Blocks

setup: cleanup:given:

when:Stimulus

then:Response, booleans are checked

expect: where:

Blocks

when:Contents are arbitrary

then:conditionsexceptionsinteractions (mocks described below)

when/then Always occur together

when: and then:

Sweet method in Specification class

expression value beforewhen 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

Sql sql = Sql.newInstance(...)

@Shared

Demo: RESTful services

@Shared

thrown()

then:

thrown(SqlException)

-- or --SqlException e = thrown()

e.sqlCode == ...

Can do work after catching exception

Exceptions are exceptions evil or just goatees?

notThrown(Class)

noExceptionThrown()

Exceptions

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() == length

where:

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 == z

where:

[x,y,z] << sql.rows(

'select x,y,z from ...')

where: clause

Display separate messagefor each row of data

@Unroll

def "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'

Use >>> operatorlist.get(0) >>> ['a', 'b']

First call to get(0) → 'a'

Second and sub calls → 'b'

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

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

@Timeoutdefault time is sec

@Timeout(5)

@Timeout(value = 100,unit = TimeUnit.MILLISECONDS)

Extensions

@IgnoreDon't run a particular test or test classOptional value = reason

@IgnoreRestDon't run any OTHER tests

Extensions

@IgnoreIf({ os.windows })Run everywhere other than windows

@Requires({ os.windows })Run only on windows

Extensions

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

Source code for examples is from1. spock-example project

https://github.com/spockframework/spock-example2. my GitHub repo

https://github.com/kousen/spock-workshop

Examples

Please complete your session evals

Session Evals