Perform some action when spec fails in Spock Framework

Let’s imagine that we need to perform a certain sequence of actions when a spec fails. If you just need to close some resources when spec fails – don’t reinvent the wheel and use an easy and correct method – @AutoCleanup annotation. I wrote about it in detail earlier: https://mchesnavsky.tech/closing-resources-in-spock-framework.

Keep in mind that in addition to the usual closure of resources, you can use the annotation to your advantage in this case as well. Create a class that will do what you need in the close() method, create an object of this class and put this annotation above it.

If all of the above methods do not work for you, you can write your own handler. Firstly, we need to implement the IGlobalExtension interface in our spec as follows:

class YourSpec implements IGlobalExtension {
    @Override
    void visitSpec(SpecInfo specInfo) {
        specInfo.addListener(new AbstractRunListener() {
            void error(ErrorInfo error) {
                // Your action
            }
        })
    }
     
    @Override
    void start() { }
     
    @Override
    void stop() { }
}

Then create a new file called org.spockframework.runtime.extension.IGlobalExtension and place it in META-INF/services folder in your jar. Put just one line to this file – the full name of the spec class (for example, org.example.YourSpec) that implements the IGlobalExtension interface.

An important addition!

META-INF/services already has a file called org.spockframework.runtime.extension.IGlobalExtension and some default system lines. We may accidentally replace it with our one-line file. To prevent this from happening, the maven-shade-plugin has an AppendingTransformer that will merge the contents of these two files into one. Below is the maven-shade-plugin plugin config:

<configuration>
    <transformers>
        <!-- AppendingTransformer is necessary so that our configuration does not overwrite, but complements the standard one -->
        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/services/org.spockframework.runtime.extension.IGlobalExtension</resource>
        </transformer>
        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>org.example.Main</mainClass>
        </transformer>
    </transformers>
</configuration>

Telegram channel

If you still have any questions, feel free to ask me in the comments under this article or write me at promark33@gmail.com.

If I saved your day, you can support me 🤝