GitHub - jakubsob/cucumber: Behavior-Driven Development and Specifications Testing for R (original) (raw)

cucumber

R-CMD-check Codecov test coverage cucumber muttest CRAN status Grand total Last month

An implementation of the Cucumber testing framework in R.

Introduction

The package parses Gherkin documents

tests/acceptance/addition.feature

Feature: Addition Scenario: Adding 2 integers When I add 1 and 1 Then the result is 2 Scenario: Adding integer and float When I add 1 and 1.1 Then the result is 2.1 Scenario: Adding float and float When I add 1.1 and 1.1 Then the result is 2.2 Scenario: Adding float and float with signs When I add +11.1 and +11.1 Then the result is +22.2 Scenario: Adding float and float of opposite signs When I add +11.11 and -11.1 Then the result is +0.01

and uses step definitions to run the tests

tests/acceptance/setups-steps.R

when("I add {int} and {int}", function(x, y, context) { context$result <- x + y })

then("the result is {int}", function(expected, context) { expect_equal(context$result, expected) })

when("I add {int} and {float}", function(x, y, context) { context$result <- x + y })

when("I add {float} and {float}", function(x, y, context) { context$result <- x + y })

then("the result is {float}", function(expected, context) { expect_equal(context$result, expected) })

The building blocks of the cucumber tests are Features and Scenarios.

That means a successful run for an Addition feature would produce the following output (with ProgressReporter).

✔ | F W S OK | Context ✔ | 5 | Feature: Addition

══ Results ═══════════════════════════════════════════ [ FAIL 0 | WARN 0 | SKIP 0 | PASS 5 ]

and a failing one would produce:

✔ | F W S OK | Context ✖ | 1 4 | Feature: Addition ──────────────────────────────────────────────────────────────────────────── Failure (test-cucumber.R:2:1): Scenario: Adding float and float of opposite signs context$result (actual) not equal to expected (expected).

actual: 0.0100 expected: 0.0010 Backtrace: ▆

  1. └─cucumber (local) call() at cucumber/R/parse_token.R:23:13
  2. └─cucumber (local) x(context = context, ...)
  3. └─step(expected = 0.001, ...)
  4.   └─testthat::expect_equal(context$result, expected) at tests/acceptance/setup-steps-addition.R:19:3

────────────────────────────────────────────────────────────────────────────

══ Results ═════════════════════════════════════════════════════════════════ ── Failed tests ──────────────────────────────────────────────────────────── Failure (test-cucumber.R:2:1): Scenario: Adding float and float of opposite signs context$result (actual) not equal to expected (expected).

actual: 0.0100 expected: 0.0010 Backtrace: ▆

  1. └─cucumber (local) call() at cucumber/R/parse_token.R:23:13
  2. └─cucumber (local) x(context = context, ...)
  3. └─step(expected = 0.001, ...)
  4.   └─testthat::expect_equal(context$result, expected) at tests/acceptance/setup-steps-addition.R:19:3

[ FAIL 1 | WARN 0 | SKIP 0 | PASS 4 ]

Put your acceptance tests in a directory separate to your unit tests:

tests/
├── acceptance/
│   ├── setup-steps_1.R
│   ├── setup-steps_2.R
│   ├── feature_1.feature
│   ├── feature_2.feature
├── testthat/
│   ├── test-unit_test_1.R
│   ├── test-unit_test_2.R

or alongside your unit tests:

tests/
├── testthat/
│   ├── test-cucumber.R
│   ├── test-unit_test_1.R
│   ├── test-unit_test_2.R
│   ├── setup-steps_1.R
│   ├── setup-steps_2.R
│   ├── feature_1.feature
│   ├── feature_2.feature

Examples

See the examples directory to help you get started.

How it works

The .feature files are parsed and matched against step definitions.

Step functions are defined using:

If a step parsed from one of .feature files is not found, an error will be thrown.

Parameter types

Step implementations receive data from the .feature files as parameters. The values are detected via regular expressions and cast with a transformer function.

The following parameter types are available by default:

Parameter Type Description
{int} Matches integers, for example 71 or -19. Converts value with as.integer.
{float} Matches floats, for example 3.6, .8 or -9.2. Converts value with as.double.
{word} Matches words without whitespace, for example banana (but not banana split).
{string} Matches single-quoted or double-quoted strings, for example "banana split" or 'banana split' (but not banana split). Only the text between the quotes will be extracted. The quotes themselves are discarded.

See cucumber::define_parameter_type() how to define your own parameter types.

Supported Gherkin syntax:

Installation

To install the stable version from CRAN:

install.packages("cucumber")