@@ -351,63 +351,27 @@ With the flag `applyGlobalTimeoutToFixtures` you can control if the global timeo
351351The `@Retry` extensions can be used for flaky integration tests, where remote systems can fail sometimes.
352352By default it retries an iteration `3` times with `0` delay if either an `Exception` or `AssertionError` has been thrown, all this is configurable.
353353In addition, an optional `condition` closure can be used to determine if a feature should be retried.
354- It also provides special support for data driven features, offering to either retry all iterations or just the failing ones.
354+ In its standard mode it only retries the feature method execution, but this can be changed using `mode` to
355+ also run setup and cleanup on retries. Even in this mode, the retry is only triggered if the feature method is failing
356+ in the expected way. If the setup or cleanup is failing, the test fails immediately.
355357
356358[source,groovy]
357359----
358- class FlakyIntegrationSpec extends Specification {
359- @Retry
360- def retry3Times() { ... }
361-
362- @Retry(count = 5)
363- def retry5Times() { ... }
364-
365- @Retry(exceptions=[IOException])
366- def onlyRetryIOException() { ... }
367-
368- @Retry(condition = { failure.message.contains('foo') })
369- def onlyRetryIfConditionOnFailureHolds() { ... }
370-
371- @Retry(condition = { instance.field != null })
372- def onlyRetryIfConditionOnInstanceHolds() { ... }
373-
374- @Retry
375- def retryFailingIterations() {
376- ...
377- where:
378- data << sql.select()
379- }
380-
381- @Retry(mode = Retry.Mode.FEATURE)
382- def retryWholeFeature() {
383- ...
384- where:
385- data << sql.select()
386- }
387-
388- @Retry(delay = 1000)
389- def retryAfter1000MsDelay() { ... }
390- }
360+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-common]
361+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-a]
391362----
392363
393364Retries can also be applied to spec classes which has the same effect as applying it to each feature method that isn't
394- already annotated with {@code Retry} .
365+ already annotated with `@ Retry` .
395366
396367[source,groovy]
397368----
398- @Retry
399- class FlakyIntegrationSpec extends Specification {
400- def "will be retried with config from class"() {
401- ...
402- }
403- @Retry(count = 5)
404- def "will be retried using its own config"() {
405- ...
406- }
407- }
369+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-b1]
370+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-common]
371+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-b2]
408372----
409373
410- A {@code @ Retry} annotation that is declared on a spec class is applied to all features in all subclasses as well,
374+ A `@ Retry` annotation that is declared on a spec class is applied to all features in all subclasses as well,
411375unless a subclass declares its own annotation. If so, the retries defined in the subclass are applied to all feature
412376methods declared in the subclass as well as inherited ones.
413377
@@ -416,25 +380,7 @@ Running `BarIntegrationSpec` will execute `inherited` and `bar` with two retries
416380
417381[source,groovy]
418382----
419- @Retry(count = 1)
420- abstract class AbstractIntegrationSpec extends Specification {
421- def inherited() {
422- ...
423- }
424- }
425-
426- class FooIntegrationSpec extends AbstractIntegrationSpec {
427- def foo() {
428- ...
429- }
430- }
431-
432- @Retry(count = 2)
433- class BarIntegrationSpec extends AbstractIntegrationSpec {
434- def bar() {
435- ...
436- }
437- }
383+ include::{sourcedir}/extension/RetryDocSpec.groovy[tag=example-c]
438384----
439385
440386Check https://github.com/spockframework/spock/blob/master/spock-specs/src/test/groovy/org/spockframework/smoke/extension/RetryFeatureExtensionSpec.groovy[RetryFeatureExtensionSpec] for more examples.
0 commit comments