This page explains incompatible changes between successive versions and provides suggestions on how to deal with them.

2.0

  • The default unroll pattern changed from the rather generic #featureName[#iterationIndex] to a more fancy version that lists all data variables and their values additionally to the feature name and iteration index. If you prefer to retain the old behaviour, you can set the setting unroll { defaultPattern '#featureName[#iterationIndex]' } in the Spock configuration file and you will get the same result as previously.

Renamed iterationCount token

The token #iterationCount in unroll patterns was renamed to #iterationIndex. If you use it somewhere, you have to manually change it to the new name or the test will fail unless you disabled expression asserting, then you will get an #Error:iterationCount rendering instead.

No access to data variables in data pipes anymore

It is not possible anymore to access any data variable from a data pipe or anything else but a previous data table column in a data table cell. This access was partly possible, but could easily prematurely drain iterators, access data providers sooner as expected, behaved differently depending on the concrete code construct used. All these points are more confusing than necessary. If you want to calculate a data variable from others, you can always use a derived data variable that has full access to all previous data variables and can also call helper methods for more complex logic.

If you switch your tests that are fully green to use Spock 2.0 and get any MissingPropertyExceptions, you are probably hitting this change, you should then change to a derived data variable there instead of a data pipe.

If you for example had:

where:
a << [1, 2]
b << a

what you want instead is:

where:
a << [1, 2]
b = a

Assert unroll expressions by default

The system property spock.assertUnrollExpressions is not supported anymore. Instead the new default behavior is equal to having this property set to true. This means tests that were successful but had an #Error: name rendering will now fail. It can be set back to the old pre Spock 2.0 behaviour by setting unroll { validateExpressions false } in the Spock configuration file.

1.0

Specs, Spec base classes and third-party extensions may have be recompiled in order to work with Spock 1.0.

JRE 1.5 and Groovy versions below 2.0 are no longer supported.

Make sure to pick the right binaries for your Groovy version of choice: groovy-2.0 for Groovy 2.0/2.1/2.2, groovy-2.3 for Groovy 2.3, and groovy-2.4 for Groovy 2.4 and higher. Spock won’t let you run with a "wrong" version.

No known source incompatible changes.

0.7

Client code must be recompiled in order to work with Spock 0.7. This includes third-party Spock extensions and base classes.

No known source incompatible changes.

0.6

Class initialization order

Note
This only affects cases where one specification class inherits from another one.

Given these specifications:

class Base extends Specification {
    def base1 = "base1"
    def base2

    def setup() { base2 = "base2" }
}

class Derived extends Base {
    def derived1 = "derived1"
    def derived2

    def setup() { derived2 = "derived2" }
}

In 0.5, above assignments happened in the order base1, base2, derived1, derived2. In other words, field initializers were executed right before the setup method in the same class. In 0.6, assignments happen in the order base1, derived1, base2, derived2. This is a more conventional order that solves a few problems that users faced with the previous behavior, and also allows us to support JUnit’s new TestRule. As a result of this change, the following will no longer work:

class Base extends Specification {
    def base

    def setup() { base = "base" }
}

class Derived extends Base {
    def derived = base + "derived" // base is not yet set
}

To overcome this problem, you can either use a field initializer for base, or move the assignment of derived into a setup method.

@Unroll naming pattern syntax

Note
This is not a change from 0.5, but a change compared to 0.6-SNAPSHOT.
Note
This only affects the Groovy 1.8 and 2.0 variants.

In 0.5, the naming pattern was string based:

@Unroll("maximum of #a and #b is #c")
def "maximum of two numbers"() {
    expect:
    Math.max(a, b) == c

    where:
    a | b | c
    1 | 2 | 2
}

In 0.6-SNAPSHOT, this was changed to a closure returning a GString:

@Unroll({"maximum of $a and $b is $c"})
def "maximum of two numbers"() { ... }

For various reasons, the new syntax didn’t work out as we had hoped, and eventually we decided to go back to the string based syntax. See Improved @Unroll for recent improvements to that syntax.

Hamcrest matcher syntax

Note
This only affects users moving from the Groovy 1.7 to the 1.8 or 2.0 variant.

Spock offers a very neat syntax for using Hamcrest matchers:

import static spock.util.matcher.HamcrestMatchers.closeTo

...

expect:
answer closeTo(42, 0.001)

Due to changes made between Groovy 1.7 and 1.8, this syntax no longer works in as many cases as it did before. For example, the following will no longer work:

expect:
object.getAnswer() closeTo(42, 0.001)

To avoid such problems, use HamcrestSupport.that:

import static spock.util.matcher.HamcrestSupport.that

...

expect:
that answer, closeTo(42, 0.001)

A future version of Spock will likely remove the former syntax and strengthen the latter one.