Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from cucumber-java8 to cucumber-java #259

Closed
timtebeek opened this issue Sep 18, 2022 · 2 comments · Fixed by #262
Closed

Migrate from cucumber-java8 to cucumber-java #259

timtebeek opened this issue Sep 18, 2022 · 2 comments · Fixed by #262
Labels
recipe Recipe request
Milestone

Comments

@timtebeek
Copy link
Contributor

timtebeek commented Sep 18, 2022

Cucumber-JVM is an often used (GitHub search, Moderne FindType) integration testing library. Users define their tests in natural language, which through bindings are converted into executable tests. The developers behind the Java implementation are planning to deprecate the cucumber-java8 bindings. Instead, users will (most likely) have to adopt the cucumber-java bindings.

The programming models differ, but should read as a one to one translation:

cucumber-java8

package com.example.app;

import io.cucumber.java8.En;
import io.cucumber.datatable.DataTable;
import io.cucumber.docstring.DocString;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CalculatorStepDefinitions implements En {
    private RpnCalculator calc;

    public CalculatorStepDefinitions() {
        Given("a calculator I just turned on", () -> {
            calc = new RpnCalculator();
        });

        When("I add {int} and {int}", (Integer arg1, Integer arg2) -> {
            calc.push(arg1);
            calc.push(arg2);
            calc.push("+");
        });

        Then("the result is {double}", (Double expected) -> assertEquals(expected, calc.value()));
    }
}

cucumber-java

package com.example.app;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CalculatorStepDefinitions {
    private RpnCalculator calc;

    @Given("a calculator I just turned on")
    public void a_calculator_I_just_turned_on() {
        calc = new RpnCalculator();
    }

    @When("I add {int} and {int}")
    public void adding(int arg1, int arg2) {
        calc.push(arg1);
        calc.push(arg2);
        calc.push("+");
    }

    @Then("the result is {int}")
    public void the_result_is(double expected) {
        assertEquals(expected, calc.value());
    }
}

There's various language bindings which may be supported, such as io.cucumber.java8.En & io.cucumber.java8.Nl, which respectively will need to move to annotations such as @io.cucumber.java.en.Given & @io.cucumber.java.nl.Gegeven.

It's debatable if such a migration should be part of this library, as JUnit, AssertJ, Mockito & WireMock before it, or whether this would better fit in with the cucumber-jvm repository itself.

@timtebeek
Copy link
Contributor Author

timtebeek commented Sep 20, 2022

Some notes from a first manual migration (20 more to go 😭):

  1. imports of interfaces such as io.cucumber.java8.En can be replaced with io.cucumber.java.en.*
  2. Before(() -> {...}) becomes a method annotated with io.cucumber.java.Before, not any JUnit annotation
  3. any other method invocations can typically be replaced by a similarly named annotation placed on a new method
  4. the new methods need generated names, possibly taken from snake_cased expression
  5. annotated methods need to be public
  6. comments in between method calls need to be relocated to be in between annotated methods
  7. cucumber-java8 dependency can be removed
  8. generated methods should throw any checked exceptions from within StepDefinitionBody

@pway99 pway99 moved this to Recipes Wanted in OpenRewrite Sep 21, 2022
@timtebeek
Copy link
Contributor Author

Some very rough work in progress here. Could not get the visitor for the interface default method invocation to work; so all is now in one big constructor visitor. Doubtful of the current doAfterVisit setup at the end; any feedback appreciated.

Repository owner moved this from Recipes Wanted to Done in OpenRewrite Sep 30, 2022
@tkvangorder tkvangorder added this to the 1.29.0 milestone Oct 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
recipe Recipe request
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants