18

I've got a Cucumber Step class that i'm attempting to initialise a page model for all scenarios. So I added a @Before annotated method :

@Before()
private void beforeScenario() {
    LOGGER.info("Running before!");
    loginPage = BrowserDriver.getPageModel(LoginPage.class);
}

I've then got a bunch of steps that rely on loginPage being set. e.g.

@When("^I click the help link$")
public void I_click_the_help_link() {
    loginPage.clickHelpLink();
}

I have multiple Step classes. Both of the methods above are in the same same Step class. However loginPage is always null. The beforeScenario method is never being called. Have I completely misunderstood how @Before is meant to work? Any tips on how to get what I want to work?

Edit : I also have an @After annotated method that does get run after every scenario as expected.

Edit : Pom can be seen at : http://pastebin.com/PJ6qQRK9

7
  • How do you know beforeScenario is never called. Have you tried with inserting a println there. Try and see if it is getting printed. Commented Jun 4, 2014 at 7:59
  • I know it's never called because I put breakpoints in there when running in my IDE and I never hit them. I also know because the LOGGER.info("Running after!") line in my @After annotated method shows in my logs while the expected log line for the beforeScenario is not written to the logs. Commented Jun 5, 2014 at 4:05
  • Check your cucumber.yml whether you have pasted the hooks path in that Commented Jun 5, 2014 at 7:44
  • It works for me with version 1.1.5 and 1.1.6. Which version are you on? Commented Jun 5, 2014 at 8:21
  • @Bala : I was version 1.1.7, but downgrading to 1.1.5 doesn't help. Commented Jun 5, 2014 at 9:02

8 Answers 8

57
  1. Make sure you are using cucumber.annotation.Before rather than org.junit.Before. Cucumber will not process JUnit annotations. (More information in the Scenario Hooks section of this blog post.)

  2. Make sure your @Before method is public, not private.

Sign up to request clarification or add additional context in comments.

5 Comments

I got excited when I saw this post as it seemed a likely issue and an easy oversight. However I'm using the cucumber.api.java.Before annotation. I can't find cucumber.annotation.Before, I presume it was removed in later releases.
I've had a play about with some of my cucumber-jvm tests and I think I've spotted it. Your @Before method should be public rather than private
Easy oversight number 2 has it. Thanks a ton, that's a great spot.
import cucumber.api.java.Before; is the correct import
cucumber.annotation.Before is not a correct location, but cucumber.api.java.Before is as of cucumber-java 7.2.3 , Apr,2022
19

Hello I know that is an old post, but none of these solutions work for me. So I'm going to share my solution.

I created the class Hooks under the package: com.mycompany.automation.util

package com.mycompany.automation.util;

import com.mycompany.automation.rest.database.AS400DBManager;
import cucumber.api.java.After;
import java.sql.SQLException;

/**
 * @author <a href="[email protected]">Julian Mesa</a>
 * @version 0.1.0
 * @since 0.1.0
 */

    public class Hooks {

      @After
      public void beforeScenario() throws SQLException, ClassNotFoundException {
        System.out.print("Closing connection.");
        AS400DBManager.getInstance().closeConnection();
      }

    }

and then I specified the package in the glue options in the runner:

@RunWith(CucumberWithSerenity.class)
@CucumberOptions(
    features = "src/test/resources/features",
    glue = {"com.mycompany.automation.features.steps",
        "com.mycompany.automation.util"}
)

And it worked.

2 Comments

Yeah thanks for the answer ; to improve the answer, the trick lies in including package as 'glue' param.
This is where mostly people mistake. forget to mention package name in runner if hooks created in separate package. Nice answer. +1
6

There is an accepted answer to this question, but I wanted to point out the comment made by Matt Watson which solved the issue for me and for which I have not seen similar advice elsewhere:

I've had a play about with some of my cucumber-jvm tests and I think I've spotted it. Your @Before method should be public rather than private

The @Before method must be public.

Comments

2

I know this Is an old issue but I found a Solution using the 5.5.0 version of cucumber java: I added the Hooks class into the Steps package, having only the glue="Step classpath" and it worked fine for me :)

Hope that helps!!

Comments

1

I know this issue is old, but in case somebody runs into the same problem using IntelliJ:

Check the "Glue"-Property in your Run/Debug Configuration. This is the list of paths that Glue (the autowirering-system from Cucumber) uses to find Classes to wire.
It seems like IntelliJ is generating this property, if it is not specifically defined in the the Template for "Cucumber Java"-Configs.

I don't know how it is generated, but for me the package that contains my class with the Before-Method in question did not exist. After adding it everything worked normally.

Edit:

Found out more background-info. The IntelliJ Cucumber Plugin does not use Junit oder TestNG, but his own implemented runner suite. This runner does NOT interepret the Annotation-Based configurations from Cucumber, only the ones from the Cucumber Property-File or System-Properties. The TestNG-Suite however always overwrites the Glue-Path, not matter if it was actually set or is present. The most consistent way I found was to configure it both using annotations and properties. That way you are always sure that you're config ist used (Gradle-Runner, TestNG-Runner, IntellijCucumber-Runner)

1 Comment

This helped me. I would also say than you can analyze with what parameters your tests run by copying this line (i.imgur.com/pKbhyns.png) and search for a "glue" word, then you will be able to identify what parameters intellij uses to run tests
1

Check my test runner classs glueing the hooks in test runner has solved the issue i have defined hooks in this package "com.memberweb.utilities"

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/resources/features",
        glue = {"com/memberweb/stepDefinitions","com.memberweb.utilities"},
        plugin = {"pretty",
                "html:target/cucumber-reports/cucumber.html",
                "json:target/cucumber-reports/CucumberTestReport.json"
                },
        monochrome = true
)
public class testRunner {

    }

Comments

0

In my case worked the addition of a package where @Before was defined to the glue parameter:

@CucumberOptions(glue = {"cucumber.hook", "cucumber.steps"})

Comments

0

In my case, it has worked when I put "dryRun = false" in the Cucumber options.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.