How it works

When `cucumber::test` is called, it scans for the `.feature` files in the `features_dir` directory.

It parses the feature files and runs the step implementations one by one, according to their order in feature files.

# Step execution order

Given such a feature file:

    # tests/testthat/sum.feature
    Feature: Sum
      Scenario: Sum should work for 2 numbers
        Given I have 1
        And I have 2
        When I add them
        Then I get 3

      Scenario: Sum should work for 3 numbers
        Given I have 1
        And I have 2
        But I have 3
        When I add them
        Then I get 6

And such step definitions:

    # tests/testthat/steps/steps_definitions.R
    given("I have {int}", function(int, context) {
      print("given")
      context$numbers <- c(context$numbers, int)
    })

    when("I add them", function(context) {
      print("when")
      context$result <- sum(context$numbers)
    })

    then("I get {int}", function(int, context) {
      print("then")
      expect_equal(context$result, int)
    })

The order of calling the steps would be:

    > [1] "given"
    > [1] "given"
    > [1] "when"
    > [1] "then"
    > [1] "given"
    > [1] "given"
    > [1] "given"
    > [1] "when"
    > [1] "then"

# Translation to `testthat` code

Cucumber translates `.feature` files to `testthat::test_that` calls.

When a `Scenario` is run, the `context` environment is reset so that the state doesn’t leak to the next scenario.

The previous feature file is basically translated to the following test code, so that we can leverage testthat reporters and not reinvent the wheel.

    test_that("Scenario: Sum should work for 2 numbers", {
      context <- new.env()
      context$numbers <- c(context$numbers, 1)
      context$numbers <- c(context$numbers, 2)
      context$result <- sum(context$numbers)
      expect_equal(context$result, 3)
    })

    test_that("Scenario: Sum should work for 3 numbers", {
      context <- new.env()
      context$numbers <- c(context$numbers, 1)
      context$numbers <- c(context$numbers, 2)
      context$numbers <- c(context$numbers, 3)
      context$result <- sum(context$numbers)
      expect_equal(context$result, 6)
    })

Test successes or failures are reported at the level of Scenarios.

A scenario is a test case.

# How step definitions are loaded

If you define your steps in setup or helper files you don’t have to load step implementations manually. Cucumber will load them automatically when `cucumber::test` is called.

If you don’t want them to be loaded automatically from the default location, you can create your own command that calls `cucumber::test()` and loads the step definitions from the desired location.

Steps from feature files are matched against step definitions defined with `given()`, `when()`, and `then()` functions using regular expressions.

When you define a step by calling any of the step functions, you register that step, making it available for the tests.