SlideShare ist ein Scribd-Unternehmen logo
1 von 60
Downloaden Sie, um offline zu lesen
Spocktacular Testing 
Russel Winder 
email: russel@winder.org.uk 
xmpp: russel@winder.org.uk 
twitter: @russel_winder 
Web: http://www.russel.org.uk 
Copyright © 2014 Russel Winder 1
Opening 
Copyright © 2014 Russel Winder 2
Copyright © 2014 Russel Winder 3
An Historical Perspective 
Copyright © 2014 Russel Winder 4
Spock 
BDD 
JBehave 
sUnit 
TestNG 
JUnit4 
JUnit 
GroovyTestCase 
RSpec 
TDD 
Copyright © 2014 Russel Winder 5
Spock is Groovy-based… 
…but can test any JVM-based code. 
Copyright © 2014 Russel Winder 6
NB Testing frameworks support integration 
and system testing as well as unit testing. 
Copyright © 2014 Russel Winder 7
Copyright © 2014 Russel Winder 8
Testing 
● Unit: 
● Test the classes, 
functions and methods 
to ensure they do 
what we need them to. 
● As lightweight and fast 
as possible. 
● Run all tests always. 
● Integration and system: 
● Test combinations or the 
whole thing to make sure 
the functionality is as 
required. 
● Separate process to create 
a “sandbox”. 
● If cannot run all tests 
always, create smoke tests. 
Copyright © 2014 Russel Winder 9
Code Under Test 
static message() { 
'Hello World.' 
} 
println message() 
helloWorld.groovy 
Copyright © 2014 Russel Winder 10
Unit Test 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import helloWorld 
class Test_HelloWorld extends Specification { 
def 'ensure the message function returns hello world'() { 
expect: 
helloWorld.message() == 'Hello World.' 
} 
} 
Copyright © 2014 Russel Winder 11
System Test 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
class Test_HelloWorld extends Specification { 
def 'executing the script results in hello world on the standard output'() { 
given: 
def process = 'helloWorld.groovy'.execute() 
expect: 
process.waitFor() == 0 
process.in.text == 'Hello World.n' 
} 
} 
Copyright © 2014 Russel Winder 12
A bit less Groovy… 
Copyright © 2014 Russel Winder 13
Code under Test 
package uk.org.winder.spockworkshop; 
class HelloWorld { 
private static String message() { 
return "Hello World."; 
} 
public static void main(final String[] args) { 
System.out.println(message()); 
} 
} 
HelloWorld.java 
Copyright © 2014 Russel Winder 14
Unit Test 
package uk.org.winder.spockworkshop 
import spock.lang.Specification 
class UnitTest_HelloWorld extends Specification { 
def 'ensure the message function returns hello world'() { 
expect: 
HelloWorld.message() == 'Hello World.' 
} 
} 
Copyright © 2014 Russel Winder 15
System Test 
package uk.org.winder.spockworkshop 
import spock.lang.Specification 
class SystemTest_HelloWorld extends Specification { 
def 'executing the program results in hello world on the standard output'() { 
given: 
def process = ['java', '-cp', 'build/classes/main', 
'uk.org.winder.spockworkshop.HelloWorld'].execute() 
expect: 
process.waitFor() == 0 
process.in.text == 'Hello World.n' 
} 
} 
Copyright © 2014 Russel Winder 16
Project Structure 
. 
├── build.gradle 
└── src 
├── main 
│ └── java 
│ └── uk 
│ └── org 
│ └── winder 
│ └── spockworkshop 
│ └─- HelloWorld.java 
└── test 
└── groovy 
└── uk 
└── org 
└── winder 
└── spockworkshop 
└── SystemTest_HelloWorld.groovy 
└── UnitTest_HelloWorld.groovy 
Copyright © 2014 Russel Winder 17
Build — Gradle 
apply plugin: 'groovy' 
apply plugin: 'application' 
repositories { 
mavenCentral() 
} 
dependencies { 
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' 
} 
mainClassName = 'uk.org.winder.spockworkshop.HelloWorld' 
Copyright © 2014 Russel Winder 18
Copyright © 2014 Russel Winder 19
Moving On 
Copyright © 2014 Russel Winder 20
Copyright © 2014 Russel Winder 21
Spock Test Structure 
Copyright © 2014 Russel Winder 22
given: 
Copyright © 2014 Russel Winder 23
Code Under Test 
static message() { 
'Hello World.' 
} 
println message() 
helloWorld.groovy 
Copyright © 2014 Russel Winder 24
Unit Test 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import helloWorld 
class Test_HelloWorld extends Specification { 
def 'ensure the message function returns hello world'() { 
expect: 
helloWorld.message() == 'Hello World.' 
} 
} 
Copyright © 2014 Russel Winder 25
System Test 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
class Test_HelloWorld extends Specification { 
def 'executing the script results in hello world on the standard output'() { 
given: 
def process = 'helloWorld.groovy'.execute() 
expect: 
process.waitFor() == 0 
process.in.text == 'Hello World.n' 
} 
}
Another Code Under Test 
class Stuff { 
private final data = [] 
def leftShift(datum) { 
data << datum 
} 
} 
Stuff.groovy 
Copyright © 2014 Russel Winder 27
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import Stuff 
class TestStuff extends Specification { 
def 'check stuff'() { 
given: 
def stuff = new Stuff() 
expect: 
stuff.data == [] 
when: 
stuff << 6 
then: 
stuff.data == [6] 
when: 
stuff << 6 
then: 
stuff.data == [6, 6] 
} 
Unit Testing It 
def 'check other stuff'() { 
given: 
def stuff = new Stuff() 
expect: 
stuff.data == [] 
when: 
stuff.leftShift(6) 
then: 
stuff.data == [6] 
when: 
stuff.leftShift(6) 
then: 
stuff.data == [6, 6] 
} 
} 
Copyright © 2014 Russel Winder 28
Copyright © 2014 Russel Winder 29
Data-driven Testing 
Copyright © 2014 Russel Winder 30
Copyright © 2014 Russel Winder 31
given: 
Copyright © 2014 Russel Winder 32
Code Under Test 
Id.groovy 
class Id { 
def eval(x) { x } 
} 
Copyright © 2014 Russel Winder 33
Unit Test Code 
#! /usr/bin/env groovy 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import spock.lang.Unroll 
class idTest extends Specification { 
@Unroll def 'id.eval always returns the value of the parameter: #i'() { 
given: 
final id = new Id () 
expect: 
id.eval(i) == i 
where: 
i << [0, 1, 2, 3, 's', 'ffff', 2.05] 
} 
} 
Copyright © 2014 Russel Winder 34
Code Under Test 
class Functions { 
static square(x) { x * x } 
} 
Functions.groovy 
Copyright © 2014 Russel Winder 35
Unit Test — Variant 1 
#! /usr/bin/env groovy 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import spock.lang.Unroll 
class functionsTest_alt_1 extends Specification { 
@Unroll def 'square always returns the square of the parameter: #x'() { 
expect: 
Functions.square(x) == r 
where: 
x << [0, 1, 2, 3, 1.5] 
r << [0, 1, 4, 9, 2.25] 
} 
} 
Copyright © 2014 Russel Winder 36
Unit Test — Variant 2 
#! /usr/bin/env groovy 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import spock.lang.Unroll 
class functionsTest_alt_2 extends Specification { 
@Unroll def 'square always returns the square of the parameter: #x'() { 
expect: 
Functions.square(x) == r 
where: 
[x, r] << [[0, 0], [1, 1], [2, 4], [3, 9], [1.5, 2.25]] 
} 
} 
Copyright © 2014 Russel Winder 37
#! /usr/bin/env groovy Unit Test — Tabular 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
import spock.lang.Unroll 
class functionsTest extends Specification { 
@Unroll def 'square always returns the square of the numeric parameter'() { 
expect: 
Functions.square(x) == r 
where: 
x | r 
0 | 0 
1 | 1 
2 | 4 
3 | 9 
1.5 | 2.25 
} 
} 
Copyright © 2014 Russel Winder 38
Exceptions 
Copyright © 2014 Russel Winder 39
Copyright © 2014 Russel Winder 40
Code Under Test 
class Exceptional { 
def trySomething() { 
throw new RuntimeException('Stuff happens.') 
} 
} 
Exceptional.groovy 
Copyright © 2014 Russel Winder 41
Unit Test 
#! /usr/bin/env groovy 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
class ExceptionalTest extends Specification { 
def 'trying something always results in an exception'() { 
given: 
final e = new Exceptional () 
when: 
e.trySomething() 
then: 
thrown(RuntimeException) 
} 
} 
Copyright © 2014 Russel Winder 42
Now we can do data validation 
and 
testing of error situations. 
Copyright © 2014 Russel Winder 43
Copyright © 2014 Russel Winder 44
Being More Adventurous 
Copyright © 2014 Russel Winder 45
Copyright © 2014 Russel Winder 46
Spock 
BDD 
jBehave 
sUnit 
TestNG 
JUnit4 
JUnit 
GroovyTestCase 
RSpec 
TDD 
Copyright © 2014 Russel Winder 47
Specify Behaviours – 1/4 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
class StackSpecification extends Specification { 
def 'newly created stacks are empty'() { 
given: 'a newly created stack' 
expect: 'the resulting stack to be empty.' 
} 
Copyright © 2014 Russel Winder 48
Specify Behaviours – 2/4 
def 'removing an item from a non-empty stack gives a value and changes the stack.'() { 
given: 'a new stack' 
and: 'an item to put on the stack' 
when: 'the item is added' 
then: 'the stack is not empty' 
when: 'an item is removed' 
then: 'the item we retrieved is the original and the stack is empty' 
} 
} 
Copyright © 2014 Russel Winder 49
Specify Behaviours – 3/4 
@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
import spock.lang.Specification 
class StackSpecification extends Specification { 
def 'newly created stacks are empty'() { 
given: 'a newly created stack' 
def stack = new Stack () 
expect: 'the resulting stack to be empty.' 
stack.size() == 0 
} 
Copyright © 2014 Russel Winder 50
Specify Behaviours – 4/4 
def 'removing an item from a non-empty stack gives a value and changes the stack.'() { 
given: 'a new stack' 
def stack = new Stack () 
and: 'an item to put on the stack' 
def item = 25 
and: 'a variable to store the result of activity' 
def result 
when: 'the item is added' 
stack.push(item) 
then: 'the stack is not empty' 
stack.size() == 1 
when: 'an item is removed' 
result = stack.pop() 
then: 'the item we retrieved is the original and the stack is empty' 
result == item && stack.size() == 0 
} 
} 
Copyright © 2014 Russel Winder 51
Copyright © 2014 Russel Winder 52
Closing 
Copyright © 2014 Russel Winder 53
Hopefully everyone has had some fun 
and 
learnt some useful things. 
Copyright © 2014 Russel Winder 54
Copyright © 2014 Russel Winder 55
Copyright © 2014 Russel Winder 56
Copyright © 2014 Russel Winder 57
Copyright © 2014 Russel Winder 58
The End 
Copyright © 2014 Russel Winder 59
Spocktacular Testing 
Russel Winder 
email: russel@winder.org.uk 
xmpp: russel@winder.org.uk 
twitter: @russel_winder 
Web: http://www.russel.org.uk 
Copyright © 2014 Russel Winder 60

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (19)

Unit testing with Spock Framework
Unit testing with Spock FrameworkUnit testing with Spock Framework
Unit testing with Spock Framework
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
The Ring programming language version 1.9 book - Part 81 of 210
The Ring programming language version 1.9 book - Part 81 of 210The Ring programming language version 1.9 book - Part 81 of 210
The Ring programming language version 1.9 book - Part 81 of 210
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
The Ring programming language version 1.4 book - Part 19 of 30
The Ring programming language version 1.4 book - Part 19 of 30The Ring programming language version 1.4 book - Part 19 of 30
The Ring programming language version 1.4 book - Part 19 of 30
 
Celery
CeleryCelery
Celery
 
Js tacktalk team dev js testing performance
Js tacktalk team dev js testing performanceJs tacktalk team dev js testing performance
Js tacktalk team dev js testing performance
 
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
 
Apache ZooKeeper
Apache ZooKeeperApache ZooKeeper
Apache ZooKeeper
 
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
 
The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196The Ring programming language version 1.7 book - Part 75 of 196
The Ring programming language version 1.7 book - Part 75 of 196
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
 
Service Discovery. Spring Cloud Internals
Service Discovery. Spring Cloud InternalsService Discovery. Spring Cloud Internals
Service Discovery. Spring Cloud Internals
 
The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202The Ring programming language version 1.8 book - Part 77 of 202
The Ring programming language version 1.8 book - Part 77 of 202
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 
Testing in android
Testing in androidTesting in android
Testing in android
 
Python twisted
Python twistedPython twisted
Python twisted
 
Docker In Bank Unrated
Docker In Bank UnratedDocker In Bank Unrated
Docker In Bank Unrated
 
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
How and Why Prometheus' New Storage Engine Pushes the Limits of Time Series D...
 

Andere mochten auch

Andere mochten auch (8)

GPars Remoting
GPars RemotingGPars Remoting
GPars Remoting
 
Are Go and D threats to Python
Are Go and D threats to PythonAre Go and D threats to Python
Are Go and D threats to Python
 
Tales from the Workshops
Tales from the WorkshopsTales from the Workshops
Tales from the Workshops
 
Is Groovy static or dynamic
Is Groovy static or dynamicIs Groovy static or dynamic
Is Groovy static or dynamic
 
Dance4Life - The Heroes Universe
Dance4Life - The Heroes UniverseDance4Life - The Heroes Universe
Dance4Life - The Heroes Universe
 
Dataflow: the concurrency/parallelism architecture you need
Dataflow: the concurrency/parallelism architecture you needDataflow: the concurrency/parallelism architecture you need
Dataflow: the concurrency/parallelism architecture you need
 
GPars 2014
GPars 2014GPars 2014
GPars 2014
 
Making Python computations fast
Making Python computations fastMaking Python computations fast
Making Python computations fast
 

Ähnlich wie Spocktacular testing

Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Robot Media
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
mlilley
 
Real world cross-platform testing
Real world cross-platform testingReal world cross-platform testing
Real world cross-platform testing
Peter Edwards
 

Ähnlich wie Spocktacular testing (20)

Spocktacular Testing - Russel Winder
Spocktacular Testing - Russel WinderSpocktacular Testing - Russel Winder
Spocktacular Testing - Russel Winder
 
Agile Swift
Agile SwiftAgile Swift
Agile Swift
 
Unit Testing with Foq
Unit Testing with FoqUnit Testing with Foq
Unit Testing with Foq
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
Python testing
Python  testingPython  testing
Python testing
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
 
Tdd & unit test
Tdd & unit testTdd & unit test
Tdd & unit test
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
 
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan KustInfinum Android Talks #17 - Testing your Android applications by Ivan Kust
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
 
JavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassleJavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassle
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
 
Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!Integration tests: use the containers, Luke!
Integration tests: use the containers, Luke!
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
 
Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)
 
Real world cross-platform testing
Real world cross-platform testingReal world cross-platform testing
Real world cross-platform testing
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
 
DevoxxFR17 - Préparez-vous à la modularité selon Java 9
DevoxxFR17 - Préparez-vous à la modularité selon Java 9DevoxxFR17 - Préparez-vous à la modularité selon Java 9
DevoxxFR17 - Préparez-vous à la modularité selon Java 9
 

Mehr von Russel Winder

Mehr von Russel Winder (20)

On Concurrency and Parallelism in the JVMverse
On Concurrency and Parallelism in the JVMverseOn Concurrency and Parallelism in the JVMverse
On Concurrency and Parallelism in the JVMverse
 
The Case for Kotlin and Ceylon
The Case for Kotlin and CeylonThe Case for Kotlin and Ceylon
The Case for Kotlin and Ceylon
 
On the Architectures of Microservices: the next layer
On the Architectures of Microservices: the next layerOn the Architectures of Microservices: the next layer
On the Architectures of Microservices: the next layer
 
Fast Python? Don't Bother
Fast Python? Don't BotherFast Python? Don't Bother
Fast Python? Don't Bother
 
Making Computations Execute Very Quickly
Making Computations Execute Very QuicklyMaking Computations Execute Very Quickly
Making Computations Execute Very Quickly
 
Java is Dead, Long Live Ceylon, Kotlin, etc
Java is Dead,  Long Live Ceylon, Kotlin, etcJava is Dead,  Long Live Ceylon, Kotlin, etc
Java is Dead, Long Live Ceylon, Kotlin, etc
 
Java is dead, long live Scala, Kotlin, Ceylon, etc.
Java is dead, long live Scala, Kotlin, Ceylon, etc.Java is dead, long live Scala, Kotlin, Ceylon, etc.
Java is dead, long live Scala, Kotlin, Ceylon, etc.
 
Java is dead, long live Scala Kotlin Ceylon etc.
Java is dead, long live Scala Kotlin Ceylon etc.Java is dead, long live Scala Kotlin Ceylon etc.
Java is dead, long live Scala Kotlin Ceylon etc.
 
Is Groovy as fast as Java
Is Groovy as fast as JavaIs Groovy as fast as Java
Is Groovy as fast as Java
 
Who needs C++ when you have D and Go
Who needs C++ when you have D and GoWho needs C++ when you have D and Go
Who needs C++ when you have D and Go
 
Java 8: a New Beginning
Java 8: a New BeginningJava 8: a New Beginning
Java 8: a New Beginning
 
Why Go is an important programming language
Why Go is an important programming languageWhy Go is an important programming language
Why Go is an important programming language
 
GPars: Groovy Parallelism for Java
GPars: Groovy Parallelism for JavaGPars: Groovy Parallelism for Java
GPars: Groovy Parallelism for Java
 
GroovyFX: or how to program JavaFX easily
GroovyFX: or how to program JavaFX easily GroovyFX: or how to program JavaFX easily
GroovyFX: or how to program JavaFX easily
 
Switch to Python 3…now…immediately
Switch to Python 3…now…immediatelySwitch to Python 3…now…immediately
Switch to Python 3…now…immediately
 
GPars Workshop
GPars WorkshopGPars Workshop
GPars Workshop
 
Given Groovy Who Needs Java
Given Groovy Who Needs JavaGiven Groovy Who Needs Java
Given Groovy Who Needs Java
 
Testing: Python, Java, Groovy, etc.
Testing: Python, Java, Groovy, etc.Testing: Python, Java, Groovy, etc.
Testing: Python, Java, Groovy, etc.
 
Why Groovy When Java 8 or Scala, or…
Why Groovy When Java 8 or Scala, or…Why Groovy When Java 8 or Scala, or…
Why Groovy When Java 8 or Scala, or…
 
Closures: The Next "Big Thing" In Java
Closures: The Next "Big Thing" In JavaClosures: The Next "Big Thing" In Java
Closures: The Next "Big Thing" In Java
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 

Spocktacular testing

  • 1. Spocktacular Testing Russel Winder email: russel@winder.org.uk xmpp: russel@winder.org.uk twitter: @russel_winder Web: http://www.russel.org.uk Copyright © 2014 Russel Winder 1
  • 2. Opening Copyright © 2014 Russel Winder 2
  • 3. Copyright © 2014 Russel Winder 3
  • 4. An Historical Perspective Copyright © 2014 Russel Winder 4
  • 5. Spock BDD JBehave sUnit TestNG JUnit4 JUnit GroovyTestCase RSpec TDD Copyright © 2014 Russel Winder 5
  • 6. Spock is Groovy-based… …but can test any JVM-based code. Copyright © 2014 Russel Winder 6
  • 7. NB Testing frameworks support integration and system testing as well as unit testing. Copyright © 2014 Russel Winder 7
  • 8. Copyright © 2014 Russel Winder 8
  • 9. Testing ● Unit: ● Test the classes, functions and methods to ensure they do what we need them to. ● As lightweight and fast as possible. ● Run all tests always. ● Integration and system: ● Test combinations or the whole thing to make sure the functionality is as required. ● Separate process to create a “sandbox”. ● If cannot run all tests always, create smoke tests. Copyright © 2014 Russel Winder 9
  • 10. Code Under Test static message() { 'Hello World.' } println message() helloWorld.groovy Copyright © 2014 Russel Winder 10
  • 11. Unit Test @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import helloWorld class Test_HelloWorld extends Specification { def 'ensure the message function returns hello world'() { expect: helloWorld.message() == 'Hello World.' } } Copyright © 2014 Russel Winder 11
  • 12. System Test @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification class Test_HelloWorld extends Specification { def 'executing the script results in hello world on the standard output'() { given: def process = 'helloWorld.groovy'.execute() expect: process.waitFor() == 0 process.in.text == 'Hello World.n' } } Copyright © 2014 Russel Winder 12
  • 13. A bit less Groovy… Copyright © 2014 Russel Winder 13
  • 14. Code under Test package uk.org.winder.spockworkshop; class HelloWorld { private static String message() { return "Hello World."; } public static void main(final String[] args) { System.out.println(message()); } } HelloWorld.java Copyright © 2014 Russel Winder 14
  • 15. Unit Test package uk.org.winder.spockworkshop import spock.lang.Specification class UnitTest_HelloWorld extends Specification { def 'ensure the message function returns hello world'() { expect: HelloWorld.message() == 'Hello World.' } } Copyright © 2014 Russel Winder 15
  • 16. System Test package uk.org.winder.spockworkshop import spock.lang.Specification class SystemTest_HelloWorld extends Specification { def 'executing the program results in hello world on the standard output'() { given: def process = ['java', '-cp', 'build/classes/main', 'uk.org.winder.spockworkshop.HelloWorld'].execute() expect: process.waitFor() == 0 process.in.text == 'Hello World.n' } } Copyright © 2014 Russel Winder 16
  • 17. Project Structure . ├── build.gradle └── src ├── main │ └── java │ └── uk │ └── org │ └── winder │ └── spockworkshop │ └─- HelloWorld.java └── test └── groovy └── uk └── org └── winder └── spockworkshop └── SystemTest_HelloWorld.groovy └── UnitTest_HelloWorld.groovy Copyright © 2014 Russel Winder 17
  • 18. Build — Gradle apply plugin: 'groovy' apply plugin: 'application' repositories { mavenCentral() } dependencies { testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' } mainClassName = 'uk.org.winder.spockworkshop.HelloWorld' Copyright © 2014 Russel Winder 18
  • 19. Copyright © 2014 Russel Winder 19
  • 20. Moving On Copyright © 2014 Russel Winder 20
  • 21. Copyright © 2014 Russel Winder 21
  • 22. Spock Test Structure Copyright © 2014 Russel Winder 22
  • 23. given: Copyright © 2014 Russel Winder 23
  • 24. Code Under Test static message() { 'Hello World.' } println message() helloWorld.groovy Copyright © 2014 Russel Winder 24
  • 25. Unit Test @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import helloWorld class Test_HelloWorld extends Specification { def 'ensure the message function returns hello world'() { expect: helloWorld.message() == 'Hello World.' } } Copyright © 2014 Russel Winder 25
  • 26. System Test @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification class Test_HelloWorld extends Specification { def 'executing the script results in hello world on the standard output'() { given: def process = 'helloWorld.groovy'.execute() expect: process.waitFor() == 0 process.in.text == 'Hello World.n' } }
  • 27. Another Code Under Test class Stuff { private final data = [] def leftShift(datum) { data << datum } } Stuff.groovy Copyright © 2014 Russel Winder 27
  • 28. @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import Stuff class TestStuff extends Specification { def 'check stuff'() { given: def stuff = new Stuff() expect: stuff.data == [] when: stuff << 6 then: stuff.data == [6] when: stuff << 6 then: stuff.data == [6, 6] } Unit Testing It def 'check other stuff'() { given: def stuff = new Stuff() expect: stuff.data == [] when: stuff.leftShift(6) then: stuff.data == [6] when: stuff.leftShift(6) then: stuff.data == [6, 6] } } Copyright © 2014 Russel Winder 28
  • 29. Copyright © 2014 Russel Winder 29
  • 30. Data-driven Testing Copyright © 2014 Russel Winder 30
  • 31. Copyright © 2014 Russel Winder 31
  • 32. given: Copyright © 2014 Russel Winder 32
  • 33. Code Under Test Id.groovy class Id { def eval(x) { x } } Copyright © 2014 Russel Winder 33
  • 34. Unit Test Code #! /usr/bin/env groovy @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import spock.lang.Unroll class idTest extends Specification { @Unroll def 'id.eval always returns the value of the parameter: #i'() { given: final id = new Id () expect: id.eval(i) == i where: i << [0, 1, 2, 3, 's', 'ffff', 2.05] } } Copyright © 2014 Russel Winder 34
  • 35. Code Under Test class Functions { static square(x) { x * x } } Functions.groovy Copyright © 2014 Russel Winder 35
  • 36. Unit Test — Variant 1 #! /usr/bin/env groovy @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import spock.lang.Unroll class functionsTest_alt_1 extends Specification { @Unroll def 'square always returns the square of the parameter: #x'() { expect: Functions.square(x) == r where: x << [0, 1, 2, 3, 1.5] r << [0, 1, 4, 9, 2.25] } } Copyright © 2014 Russel Winder 36
  • 37. Unit Test — Variant 2 #! /usr/bin/env groovy @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import spock.lang.Unroll class functionsTest_alt_2 extends Specification { @Unroll def 'square always returns the square of the parameter: #x'() { expect: Functions.square(x) == r where: [x, r] << [[0, 0], [1, 1], [2, 4], [3, 9], [1.5, 2.25]] } } Copyright © 2014 Russel Winder 37
  • 38. #! /usr/bin/env groovy Unit Test — Tabular @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification import spock.lang.Unroll class functionsTest extends Specification { @Unroll def 'square always returns the square of the numeric parameter'() { expect: Functions.square(x) == r where: x | r 0 | 0 1 | 1 2 | 4 3 | 9 1.5 | 2.25 } } Copyright © 2014 Russel Winder 38
  • 39. Exceptions Copyright © 2014 Russel Winder 39
  • 40. Copyright © 2014 Russel Winder 40
  • 41. Code Under Test class Exceptional { def trySomething() { throw new RuntimeException('Stuff happens.') } } Exceptional.groovy Copyright © 2014 Russel Winder 41
  • 42. Unit Test #! /usr/bin/env groovy @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification class ExceptionalTest extends Specification { def 'trying something always results in an exception'() { given: final e = new Exceptional () when: e.trySomething() then: thrown(RuntimeException) } } Copyright © 2014 Russel Winder 42
  • 43. Now we can do data validation and testing of error situations. Copyright © 2014 Russel Winder 43
  • 44. Copyright © 2014 Russel Winder 44
  • 45. Being More Adventurous Copyright © 2014 Russel Winder 45
  • 46. Copyright © 2014 Russel Winder 46
  • 47. Spock BDD jBehave sUnit TestNG JUnit4 JUnit GroovyTestCase RSpec TDD Copyright © 2014 Russel Winder 47
  • 48. Specify Behaviours – 1/4 @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification class StackSpecification extends Specification { def 'newly created stacks are empty'() { given: 'a newly created stack' expect: 'the resulting stack to be empty.' } Copyright © 2014 Russel Winder 48
  • 49. Specify Behaviours – 2/4 def 'removing an item from a non-empty stack gives a value and changes the stack.'() { given: 'a new stack' and: 'an item to put on the stack' when: 'the item is added' then: 'the stack is not empty' when: 'an item is removed' then: 'the item we retrieved is the original and the stack is empty' } } Copyright © 2014 Russel Winder 49
  • 50. Specify Behaviours – 3/4 @Grab('org.spockframework:spock-core:0.7-groovy-2.0') import spock.lang.Specification class StackSpecification extends Specification { def 'newly created stacks are empty'() { given: 'a newly created stack' def stack = new Stack () expect: 'the resulting stack to be empty.' stack.size() == 0 } Copyright © 2014 Russel Winder 50
  • 51. Specify Behaviours – 4/4 def 'removing an item from a non-empty stack gives a value and changes the stack.'() { given: 'a new stack' def stack = new Stack () and: 'an item to put on the stack' def item = 25 and: 'a variable to store the result of activity' def result when: 'the item is added' stack.push(item) then: 'the stack is not empty' stack.size() == 1 when: 'an item is removed' result = stack.pop() then: 'the item we retrieved is the original and the stack is empty' result == item && stack.size() == 0 } } Copyright © 2014 Russel Winder 51
  • 52. Copyright © 2014 Russel Winder 52
  • 53. Closing Copyright © 2014 Russel Winder 53
  • 54. Hopefully everyone has had some fun and learnt some useful things. Copyright © 2014 Russel Winder 54
  • 55. Copyright © 2014 Russel Winder 55
  • 56. Copyright © 2014 Russel Winder 56
  • 57. Copyright © 2014 Russel Winder 57
  • 58. Copyright © 2014 Russel Winder 58
  • 59. The End Copyright © 2014 Russel Winder 59
  • 60. Spocktacular Testing Russel Winder email: russel@winder.org.uk xmpp: russel@winder.org.uk twitter: @russel_winder Web: http://www.russel.org.uk Copyright © 2014 Russel Winder 60