spockframework / spockframework/spock

Support Multiple given/setup Blocks

Open
#2,190 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

new feature
Dominant language
Java
Stars
3.6k
Forks
483
PR merge metrics
No merged PRs in 30d

Description

Is your feature request related to a problem?

It's really hard to write heavy integration tests without multiple given blocks. Either the given block becomes very big and unreadable or one has to use @Stepwise annotation.

We use Spock extensively for our integration tests which cover full flows (e.g. purchase flow: get an offer, place an order, do the payment, generating contracts and documents, send emails, etc etc).
Since all of these tests are real HTTP requests, they are pretty slow (compared to unit tests), some of the steps can be almost a second to complete.
If you wanna keep tests totally isolated, either you have to generate the test data (i.e. putting the offer in the database to be able to place an order) every time for every test (which becomes cumbersome and unmaintainable pretty quickly) or use the existing functionality to get the system into the right state (i.e. call POST /api/offer before calling POST /api/order) which makes the test exponentially slower.
The best alternative at the moment is to use @Stepwise tests (which we do) and it works just fine 👍.

Describe the solution you'd like

Ideally it'd be wonderful to merge different steps of a test into a single test method and avoid using @Stepwise, for two reasons:

  1. That means a single spec can cover more than one scenario (AFAIK). Otherwise, if you have multiple scenarios you have to create different specs with different names which make navigation a bit unintuitive.
  2. The second reason which is more important is that it's not possible to use @RepeatUntilFailure in @Stepwise tests. We use this nice feature (repeat until failure) a lot to debug flaky tests.
  3. Sometimes it's not even possible to merge all "setup" logic into one since some of the interactions might be executed out of order.

More specifically I'm thinking about something like this:

def 'test purchase flow'() {

  given: 'a valid request to get an offer'
    // some test data to get an offer

  when: 'send a request to get an offer'
    // send POST /api/offer

  then: 'response should be correct'
    // assert the response is correct


  given: 'a valid request to place an order'
    // some test data to place an order

  when: 'send a request to place an order'
    // send POST /api/order

  then: 'response should be correct'
    // assert the response is correct

  ...
}
Describe alternatives you've considered

Currently it is possible to merge all steps into one single test, but the challenge is that either you have to make the given block very big or put the "setup" logic of each step in their "when" block which is not quite idiomatic in Spock.

I guess I understand why multiple given block is not supported, but I was wondering if there's a way to address this limitation?
Thanks.

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by studying Spock's existing handling of given/setup blocks, @Stepwise, and @RepeatUntilFailure, using the purchase-flow example as the intended behavior. Done means a single feature method can contain multiple given blocks in order, while supporting multiple scenarios and remaining compatible with repeat-until-failure behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, java
Domain
testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.