Have Spock fail a data-driven feature if an iteration fails

Viewed 75

Is there a way to do the equivalent of @Stepwise's failure behavior for a single feature? We have some integration tests that are set up such that setupSpec() kicks off a Kafka process, and then the actual test checks that each step happened. If step 3 failed, there's no reason to bother checking subsequent steps.

1 Answers

There is no built-in way to do this, but assuming you are using a recent 2.x Spock version and not 1.3 or so, a relatively simple annotation-driven Spock extension can do the trick for you.

package de.scrum_master.stackoverflow.q71414311

import org.spockframework.runtime.extension.ExtensionAnnotation

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ExtensionAnnotation(StepwiseIterationsExtension)
@interface StepwiseIterations {}
package de.scrum_master.stackoverflow.q71414311

import org.spockframework.runtime.extension.IAnnotationDrivenExtension
import org.spockframework.runtime.model.FeatureInfo
import org.spockframework.runtime.model.parallel.ExecutionMode

class StepwiseIterationsExtension implements IAnnotationDrivenExtension<StepwiseIterations> {
  @Override
  void visitFeatureAnnotation(StepwiseIterations annotation, FeatureInfo feature) {
    // Disable parallel iteration execution for @StepwiseIterations feature,
    // similarly to how @Stepwise disables it for the whole specification
    feature.setExecutionMode(ExecutionMode.SAME_THREAD)

    // If an error occurs in this feature, skip remaining iterations
    feature.getFeatureMethod().addInterceptor({ invocation ->
      try {
        invocation.proceed()
      }
      catch (Throwable t) {
        invocation.getFeature().skip("skipping subsequent iterations after failure")
        throw t
      }
    })
  }
}

Add this to your code base, annotate your iterated test with @StepwiseIterations and run it. I think the result is exactly what you are looking for.

In Spock 1.3, an similar, but more complex extension would also be possible.

I also want to express my special thanks to Leonard Brünings, Spock maintainer and boundless source of knowledge. I had a more complex version of this extension in place, but after discussing with him, it evolved into this tiny, elegant solution we are seeing here.


FYI, there is a pre-existing Spock issue #1008 requesting this feature. I created pull request #1442 which adds this capability to @Stepwise. So hopefully in the future we do not need an extra annotation and extra extension anymore.

Related