Search code examples
javacucumbercucumber-java

Value of variable being reinitialized


I have a class Reporter. Inside the constructor I have initialized a counter. The counter is incremented inside a function addStepLog. After sometime when the same counter variable is called inside the afterEachScenarioStep function the value is being initialized to 0. Please note that @AfterStep is a cucumber annotation (using cucumber-java 4.2.5). Below is my code.

public class Reporter {

      private final Object lockObject = new Object();
      private int counter;
      private List<String> stepLog;

      public Reporter() {
        stepLog = new ArrayList<>();
        counter = 0;
      }

      public void addStepLog(String message) {
        synchronized (lockObject) {
          this.counter++;
          stepLog.add(message);
        }
        System.out.println("Counter Value in addStep " + this.counter);
      }

     @AfterStep
      public void afterEachScenarioStep(Scenario scenario) {
        System.out.println("Value of Counter " + this.counter); // The value of counter is 0 here.
        if (stepLog.size() > 0) {
          System.out.println(counter++);
          synchronized (lockObject) {
            stepLog.forEach(scenario::write);
          }
        }
        scenario.embed(screenshotArray, "image/png");
      }

The size of the arryList is 0 and the counter is also reinitialized to 0. I am pretty sure cucumber is doing something funny.

I have created only one instance of Reporter from the Login class. The reporter is not being used anywhere else.

public class Login {

  private JsonParser jsonParser = new JsonParser();
  Reporter reporter = new Reporter();

  public void launchBrowser(String device) {
    reporter.addStepLog("Launched the Browser.");
    reporter.addStepLog("Launched the Browser.");
    driver(device).launchUrl(jsonParser.getValue(device, "url"));
  }

  public void clickForgotPassword(String device) {
    reporter.addStepLog("This is a dummy Step");
    reporter.addStepLog("This is a dummy Step2");
    reporter.addStepLog("This is a dummy Step3");
    reporter.addStepLog("This is a dummy Step4");
    driver(device).click("account.forgetPassword");
  }

Solution

  • Grasshopper's comment is the correct answer: cucumber-jvm destroys and re-creates the "world" (which includes all steps and glue objects) for each feature. Therefore you are getting a new instance of Reporter for each feature.

    There are some workarounds listed here: https://automationpanda.com/2017/03/03/cucumber-jvm-global-hook-workarounds/

    Static variables are the simplest workaround.