John Flinchbaugh
John Flinchbaugh

Reputation: 2338

How can Spock be made to retry failed Geb tests?

I have functional tests for a Grails app which use Geb and Spock. Occasionally, a functional test will fail for timeouts or other sporadic behavior. In previous projects using TestNG, I'd have a retryAnalyzer just trigger a retry during test execution to see if it fails both times (and then fail for real).

How do I get Spock to retry a failed test?

Upvotes: 3

Views: 3816

Answers (3)

funbiscuit
funbiscuit

Reputation: 322

In case someone runs into this. Spock has annotation Retry since version 1.2. Example usage:

import spock.lang.Retry
import spock.lang.Specification

@Retry
class SomeSpec extends Specification {
    // all features will be retried on failure
}

Or it can be applied on specific feature:

import spock.lang.Retry
import spock.lang.Specification

class SomeSpec extends Specification {
    @Retry
    def 'test something flaky'() {
        // this feature is retried up to 3 times (default)
    }

    def 'test something stable'() {
        // this feature is tested only once
    }
}

Annotation can also be applied on parent classes, in this case it is applied to all child classes (unless they declare their own annotation). By default test is retried if Exception or AssertionError are thrown.

Upvotes: 0

Chris B
Chris B

Reputation: 618

I know this question is a year old, but we've been having the same problem. Following Peter's suggestion, I created a Spock extension (https://github.com/anotherchrisberry/spock-retry).

If you have a base specification (which was our case), you can just add a @RetryOnFailure annotation to it:

@RetryOnFailure
class BaseFunctionalSpec extends Specification {
    //    all tests will execute up to two times before failing
}

Or, you can add it to a specific feature:

class SomeSpec extends Specification {

    @RetryOnFailure(times=3)
    void 'test something that fails sporadically'() {
        // will execute test up to three times before failing
    }
}

Upvotes: 9

Peter Niederwieser
Peter Niederwieser

Reputation: 123890

You'd have to write a little JUnit rule (for example something like https://gist.github.com/897229) or Spock extension. You'd probably have to live with some limitations like the same spec instance being reused and JUnit just reporting a single test, but hopefully nothing that rules out the approach altogether. (One thing that comes to mind is that mocking might not work.) In a future version of Spock, repeating a test (or its building blocks) will likely become a first-class concept, doing away with these limitations.

Upvotes: 2

Related Questions