https://jakubsob.github.io/cucumber/
Behavior-Driven Development and Specifications Testing for R
https://jakubsob.github.io/cucumber/
acceptance-testing behavior-driven-development cucumber r specification testing
Last synced: about 2 months ago
JSON representation
Behavior-Driven Development and Specifications Testing for R
- Host: GitHub
- URL: https://jakubsob.github.io/cucumber/
- Owner: jakubsob
- License: other
- Created: 2024-02-09T21:48:09.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-31T13:47:32.000Z (3 months ago)
- Last Synced: 2025-03-31T14:53:33.646Z (3 months ago)
- Topics: acceptance-testing, behavior-driven-development, cucumber, r, specification, testing
- Language: R
- Homepage: https://jakubsob.github.io/cucumber/
- Size: 8.28 MB
- Stars: 13
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: NEWS.md
- License: LICENSE
Awesome Lists containing this project
- awesome-r-pkgtools - `{cucumber}`
README
# cucumber
[](https://github.com/jakubsob/cucumber/actions/workflows/R-CMD-check.yaml)
[](https://app.codecov.io/gh/jakubsob/cucumber?branch=main)
[](https://CRAN.R-project.org/package=cucumber)
[](https://cran.r-project.org/package=cucumber)
[](https://cran.r-project.org/package=cucumber)An implementation of the [Cucumber](https://cucumber.io/) testing framework in R. Fully native, no external dependencies.
## Introduction
The package parses [Gherkin](https://cucumber.io/docs/gherkin/reference/) documents
```gherkin
# 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
```r
# 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.
- Each Feature will be treated as a separate [context](https://testthat.r-lib.org/reference/context.html?q=context#ref-usage) – their results will be reported as if they were `test-*.R` files, e.g. `'test-Feature: Addition.R'`.
- Each Scenario is equivalent to a `testthat::test_that` or `testthat::it` case. You get feedback on each Scenario separately. Only if all steps in a scenario are successful, the scenario is considered successful.That means a successful run for an `Addition` feature would produce the following output (with [ProgressReporter](https://testthat.r-lib.org/reference/ProgressReporter.html)).
```r
✔ | F W S OK | Context
✔ | 5 | Feature: Addition══ Results ═══════════════════════════════════════════
[ FAIL 0 | WARN 0 | SKIP 0 | PASS 5 ]
```and a failing one would produce:
```r
✔ | 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:
```text
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
```## Examples
See the [examples directory](https://github.com/jakubsob/cucumber/tree/main/inst/examples) to help you get started.
## How it works
The `.feature` files are parsed and matched against step definitions.
Step functions are defined using:
- `description`: a [cucumber expression](https://github.com/cucumber/cucumber-expressions).
- and an implementation function. It must have the parameters that will be matched in the description and a `context` parameter - an environment for managing state between steps.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:
- [x] Feature
- [x] Scenario
- [x] Example
- [x] Given
- [x] When
- [x] Then
- [x] And
- [x] But
- [x] *
- [x] Background
- [x] Scenario Outline (or Scenario Template)
- [x] Examples (or Scenarios)
- [ ] Rule
- [x] `"""` (Doc Strings)
- [x] `|` (Data Tables)
- [ ] `@` (Tags)
- [x] `#` (Comments)
- [x] Free-format text
- [ ] Localization# Installation
To install the stable version from CRAN:
```r
install.packages("cucumber")
```