Your SlideShare is downloading. ×
Spock
the enterprise ready specification
framework

Created by Daniel Kolman / @kolman
Spock is Groovy
...and Groovy is Bliss!

def user = new User(firstName: 'Johnny', lastName: 'Walker')
def street = company...
Spock Spec
def "can add an element"() {
given:
def list = new ArrayList<String>()
def element = "Hello Spock"
when:
list.a...
Assertions
assert name.length() == 6;

expect:
name.length() == 5

java.lang.AssertionError
Condition not satisfied:
asser...
Assertions
expect:
rectangle.getArea() == a * b
Condition not satisfied:
rectangle.getArea()
|
|
|
6
Rectangle 2 x 3

== a...
Assertions
expect:
def expectedValues =
["Legendario", "Zacapa", "Varadero", "Metusalem", "Diplomatico"]
actualValues == e...
IntelliJ IDEA can even display a diff of
expected and actual values
Mocking
given:
def sender = Mock(Sender)

Verifying behavior
with mock is simple

when:
println("nothing, hahaha!")
then:
...
Stubbing
given:
def subscriber = Mock(Subscriber)
// pattern matching
subscriber.receive("poison") >> "oh wait..."
subscri...
Data Driven Tests
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c

def "maximum of two numbers"() {
expect:
M...
QuickCheck
def "maximum of
expect:
Math.max(a,
Math.max(a,
Math.max(a,

two numbers"() {
b) == Math.max(b, a)
b) >= a && M...
Property-Based Testing
def "sorts a list"() {
when:
def sorted = list.sort(false)

You define invariant
"properties" that h...
I attended GOTO conference
in Amsterdam this year...
Erik Meijer
Haskell
LINQ
Rx

…and one of the speakers was Erik Meijer,
who was developing Haskell and worked on
LINQ and R...
Machine Learning
=> { ... }

…and he gave a great talk
about machine learning
From

Subject

Spam Filter
Body

=> { ... }

In essence, machine learning is
generating computer code based
on data

E.g. ...
Example-Based TDD
def "can detect spam"() {
expect:
spamDetector(from, subject, body) == isSpam
where:
from
'mtehnik'
'jfa...
Machine Learning
==
Automated TDD
Therefore, Erik Meijer claims
that machine learning is just
automated TDD
Prepare for the Future

In 10 years, programmers will be replaced by generated code

…and that can have some
impact on job...
Generated Code
Machine learning
Genetic programming

There are already some
real-world usages of
generated code

This is a...
Brain Research
Multilayer neural networks

…and our understanding of how
the brain works is getting better

https://www.si...
Property-Based Testing
def "sorts a list"() {
when:
def sorted = list.sort(false)
then:
sorted == sorted.sort(false)
sorte...
You will be
replaced by
machine
Meanwhile, use Spock and prosper
Credits

http://www.flickr.com/photos/kt/1217157
http://www.flickr.com/photos/rooners/7290977402
http://www.flickr.com/pho...
TestNG vs. Spock
@DataProvider(name = "maximumOfTwoNumbersProvider")
public Object[][] createDataForMaximum() {
return new...
Spock Framework
Upcoming SlideShare
Loading in...5
×

Spock Framework

1,664

Published on

Slides for my talk about Spock at jOpenSpace 2013 http://jopenspace.cz/

Published in: Technology, Education

Transcript of "Spock Framework"

  1. 1. Spock the enterprise ready specification framework Created by Daniel Kolman / @kolman
  2. 2. Spock is Groovy ...and Groovy is Bliss! def user = new User(firstName: 'Johnny', lastName: 'Walker') def street = company?.address?.street users.filter { it.age > 20 } .sort { it.salary } .collect { it.lastName + ', ' + it.firstName } def message = [subject: 'Hello jOpenSpace!', body: 'Meet me at the bar'] Groovy is dense and expressive. Don't worry it's dynamic - this is a test framework and tests are executed after every commit!
  3. 3. Spock Spec def "can add an element"() { given: def list = new ArrayList<String>() def element = "Hello Spock" when: list.add(element) then: list.size() == 1 list.contains(element) } Spock test (= "feature method") is structured into well-known blocks with defined meaning
  4. 4. Assertions assert name.length() == 6; expect: name.length() == 5 java.lang.AssertionError Condition not satisfied: assertEquals(6, name.length()); name.length() == 5 | | | Eman 4 false // hamcrest assertThat(name.length(), equalTo(6)); // FEST, AssertJ assertThat(name).hasSize(6); java.lang.AssertionError: Expected size:<6> but was:<4> in: <'Eman'> Assertions commonly used in Java are complicated or have ugly fail messages Spock makes it simple...
  5. 5. Assertions expect: rectangle.getArea() == a * b Condition not satisfied: rectangle.getArea() | | | 6 Rectangle 2 x 3 == a * b | | | | | 4 | 5 | 20 false …and when something goes wrong, it writes nice and detailed fail message
  6. 6. Assertions expect: def expectedValues = ["Legendario", "Zacapa", "Varadero", "Metusalem", "Diplomatico"] actualValues == expectedValues Condition not satisfied: actualValues == expectedValues | | | | | [Legendario, Zacapa, Varadero, Metusalem, Diplomatico] | false [Angostura, Legendario, Zacapa 23y, Varadero, Diplomatico] …even for lists
  7. 7. IntelliJ IDEA can even display a diff of expected and actual values
  8. 8. Mocking given: def sender = Mock(Sender) Verifying behavior with mock is simple when: println("nothing, hahaha!") then: 1 * sender.send(_) Too few invocations for: 1 * sender.send(_) You can use ranges for invocation count and wildcards for parameters (0 invocations) Unmatched invocations (ordered by similarity): None
  9. 9. Stubbing given: def subscriber = Mock(Subscriber) // pattern matching subscriber.receive("poison") >> "oh wait..." subscriber.receive(_) >> "ok" when: def response = subscriber.receive("poison") …and setting expectations has some powerful features // returning sequence subscriber.receive(_) >>> ["ok", "ok", "hey this is too much"] // computing return value subscriber.receive(_) >> { String msg -> msg.size() < 10 ? "ok" : "tl;dr" }
  10. 10. Data Driven Tests def "maximum of two numbers"() { expect: Math.max(a, b) == c def "maximum of two numbers"() { expect: Math.max(a, b) == expectedMax where: a << [1, 8, 9] b << [7, 3, 9] c << [7, 8, 9] where: a | b | 1 | 7 | 8 | 3 | 9 | 9 | } expectedMax 7 8 9 } Spock has first-class support for parametrized tests You can even use table-like structure for setting input data Forget JUnit theories or TestNG data providers!
  11. 11. QuickCheck def "maximum of expect: Math.max(a, Math.max(a, Math.max(a, two numbers"() { b) == Math.max(b, a) b) >= a && Math.max(a, b) >= b b) == a || Math.max(a, b) == b where: a << someIntegers() b << someIntegers() } Input data can be anything Iterable... …and that makes it simple to use something like QuickCheck for generating random data
  12. 12. Property-Based Testing def "sorts a list"() { when: def sorted = list.sort(false) You define invariant "properties" that hold true for any valid input then: sorted == sorted.sort(false) sorted.first() == list.min() sorted.last() == list.max() sorted.eachWithIndex { x, i -> assert i==0 || sorted[i-1] <= x } where: list << someLists(integers()) } Data-driven tests tend to have different structure than traditional "example-based" tests
  13. 13. I attended GOTO conference in Amsterdam this year...
  14. 14. Erik Meijer Haskell LINQ Rx …and one of the speakers was Erik Meijer, who was developing Haskell and worked on LINQ and Reactive Extensions in Microsoft...
  15. 15. Machine Learning => { ... } …and he gave a great talk about machine learning
  16. 16. From Subject Spam Filter Body => { ... } In essence, machine learning is generating computer code based on data E.g. generate a code to recognize a spam, based on analysis of bunch of email messages
  17. 17. Example-Based TDD def "can detect spam"() { expect: spamDetector(from, subject, body) == isSpam where: from 'mtehnik' 'jfabian' 'jnovotny' 'katia777' | | | | | body 'nechces nejaky slevovy kupony na viagra?' 'mels pravdu, tu znelku cz podcastu zmenime' 'penis enlargement - great vacuum pump for you' 'we have nice russian wife for you' || || || || || isSpam false false true true } And that is very similar to TDD. You are providing more and more test cases to specify the desired behavior The difference is, you don't write the implementation - it is generated by computer
  18. 18. Machine Learning == Automated TDD Therefore, Erik Meijer claims that machine learning is just automated TDD
  19. 19. Prepare for the Future In 10 years, programmers will be replaced by generated code …and that can have some impact on job security
  20. 20. Generated Code Machine learning Genetic programming There are already some real-world usages of generated code This is an antenna designed by evolutionary algorithm, that NASA actually used on a spacecraft http://idesign.ucsc.edu/projects/evo_antenna.html
  21. 21. Brain Research Multilayer neural networks …and our understanding of how the brain works is getting better https://www.simonsfoundation.org/quanta/20130723-as-machines-get-smarter-evidence-they-learn-like-us/
  22. 22. Property-Based Testing def "sorts a list"() { when: def sorted = list.sort(false) then: sorted == sorted.sort(false) sorted.first() == list.min() sorted.last() == list.max() sorted.eachWithIndex { x, i -> assert i==0 || sorted[i-1] <= x } where: list << someLists(integers()) } Now take a second look at property-based test It is only matter of time when it will be cheaper to generate code from specification than to write it manually Can there be better specification for code generator?
  23. 23. You will be replaced by machine Meanwhile, use Spock and prosper
  24. 24. Credits http://www.flickr.com/photos/kt/1217157 http://www.flickr.com/photos/rooners/7290977402 http://www.flickr.com/photos/jdhancock/4425900247 http://www.agiledojo.net/2013/09/and-now-for-somethingcompletely.html https://www.simonsfoundation.org/quanta/20130723-asmachines-get-smarter-evidence-they-learn-like-us/
  25. 25. TestNG vs. Spock @DataProvider(name = "maximumOfTwoNumbersProvider") public Object[][] createDataForMaximum() { return new Object[][]{ {1, 7, 7}, {8, 3, 8}, {9, 9, 9} }; } @Test(dataProvider = "maximumOfTwoNumbersProvider") public void maximumOfTwoNumbers(int a, int b, int expectedMax) { assertThat(Math.max(a, b)).isEqualTo(expectedMax); } def "maximum of two numbers"() { expect: Math.max(a, b) == expectedMax where: a | b | 1 | 7 | 8 | 3 | 9 | 9 | } expectedMax 7 8 9 Bonus slide - comparison of parametrized test in TestNG (above) and Spock (bellow)

×