Cucumber fixture files

Just a really quick note today (after so much time),  namely fixture files with cucumber. Ever tried to -similarly to JMock- create a fixture file, with a @Befaore and/or @After annotation in it? That would be cool, because it would result in a clean design, reused code and of course you could avoid duplications. What I mean is something like:

import cucumber.annotation.After;
import cucumber.annotation.Before;

public class MyFixture
{

    @Before
    public void setup() {
        //Awesome code here
    }

    @After
    public void tearDown() {
        //Even more awesome code here
    }
}

And then in the step definitions file:

    public class MyStepDefinitions extends MyFixture
    {
         //Awesome tests here
    }

If you haven’t tried it yet, then just don’t. If you have (like some guys I saw were asking about such things), then you know that this will result in an exception like this:

cucumber.runtime.CucumberException: You're not allowed to extend classes that define Step Definitions or hooks. class MyStepDefinitions extends class MyFixture</pre>
at cucumber.runtime.java.ClasspathMethodScanner.scan(ClasspathMethodScanner.java:64)
 at cucumber.runtime.java.ClasspathMethodScanner.scan(ClasspathMethodScanner.java:42)
 at cucumber.runtime.java.JavaBackend.loadGlue(JavaBackend.java:55)
 at cucumber.runtime.Runtime.<init>(Runtime.java:64)
 at cucumber.runtime.Runtime.<init>(Runtime.java:51)
 at cucumber.junit.Cucumber.<init>(Cucumber.java:58)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
 at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
 at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
 at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
 at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
 at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
 at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

So you can’t create a fixture file with Cuke hooks. However, if you’re using Cucumber in a Java project, than chances are quite high that you’re driving it with Spring. And if  so, you probably can do this:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MyFixture
{
    @PostConstruct
    public void setup() {
        //Awesome code here
    }

    @PreDestroy
    public void tearDown() {
        //Even more awesome code here
    }
}

As you can see those annotations are not Spring related, but don’t worry. Spring’s intelligent enough, so it can handle them. And baaaang, now we got a fixture file with a setup and a tearDown method that run before and after each test scenario. Fixture file ready, duplication eliminated.

Hope you’ll try it sometime.

Advertisements

Author: tamasgyorfi

Senior software engineer, certified enterprise architect and certified Scrum master. Feel free to connect on Twitter: @tamasgyorfi

5 thoughts on “Cucumber fixture files”

    1. Yep, it has those hooks. However, you cannot extend a class that contains these annotations. Simply put, with Cucumber @Before and @After you cannot create a hook-file that can be used by several component tests. Imagine several components, all dependant on the same service. In a setup method, you have to start the service, if not started already. You either duplicate (triplicate etc) the same service-starter code in each and every step definition, or create a fixture file that all stepdefs extend. For the latter case you need javax hooks.

  1. This is an excellent tip, and works perfectly. Thank you. Now, all I need is to do is work out how I can use this to write a @BeforeAll-type method…

  2. I’m not sure if I got it correctly, but if you have a Singleton fixture, than it will run once only. That’s certainly BeforeAll, or did you mean something different?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s