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.
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")
$numbers <- c(context$numbers, int)
context
})
when("I add them", function(context) {
print("when")
$result <- sum(context$numbers)
context
})
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"
testthat
codeCucumber 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 leverate testthat reporters and not reinvent the wheel.
test_that("Scenario: Sum should work for 2 numbers", {
<- new.env()
context $numbers <- c(context$numbers, 1)
context$numbers <- c(context$numbers, 2)
context$result <- sum(context$numbers)
contextexpect_equal(context$result, 3)
})
test_that("Scenario: Sum should work for 3 numbers", {
<- 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)
contextexpect_equal(context$result, 6)
})
Test successes or failures are reported at the level of Scenarios.
A scenario is a test case.
You don’t have to load step implementations manually. Cucumber loads them automatically when cucumber::test
is called.
If you don’t want them to be loaded automatically from the default location, you can use steps_loader
argument to provide your own step loader function. See inst/examples/custom_step_loader
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.