# Jest Cucumber Extra

Execute Gherkin scenarios in Jest with extra functionality

## Overview

jest-cucumber-extra is an alternative to [Cucumber.js](https://github.com/cucumber/cucumber-js) that is forked from [jest-cucumber](https://github.com/bencompton/jest-cucumber) and runs on top on [Jest](https://jestjs.io). Instead of using `describe` and `it` blocks, you instead write a Jest test for each scenario, and then define `Given`, `When`, and `Then` step definitions inside of your Jest tests. jest-cucumber-extra then allows you to link these Jest tests to your feature files and ensure that they always [stay in sync](./docs/AdditionalConfiguration.md#disabling-scenario--step-definition-validation).

## Motivation

Jest is an excellent test runner with great features like parallel test execution, mocking, snapshots, code coverage, etc. If you're using VS Code, there's also a terrific [Jest extension](https://github.com/jest-community/vscode-jest) that allows you get realtime feedback as you're writing your tests and easily debug failing tests individually. [Cucumber](https://cucumber.io) is a popular tool for doing [Acceptance Test-Driven Development](https://en.wikipedia.org/wiki/Acceptance_test–driven_development) and creating business-readable executable specifications. This library aims to achieve the best of both worlds, and even run your unit tests and acceptance tests in the same test runner.

## Getting Started

### Install Jest Cucumber Extra:

```
npm install jest-cucumber-extra --save-dev
```

### Add a Feature file:

```gherkin
Feature: Earth shape

  Background:
    Given properties:
      | earthShape   | unknown |
      | realityState | real    |
      And property "galaxy" is "Milky Way"

  Scenario: Round earth
    Given I am normal
    When I talk
    Then result "earthShape" should be "round"
```

### Add unit tests that link to your feature file:

```javascript
import { defineFeature, DefineStepFunction, World, loadFeature, CommonSteps } from '../src';

// Define the feature loaded from feature file
defineFeature(
  loadFeature('./basic-scenarios.feature', {
    tagFilter: 'not @excluded',
  }),
  (test) => {
    // Create "background" steps
    const background = (given: DefineStepFunction) => {
      // Utilize "common" steps for repeatable steps
      CommonSteps.givenProperties(given);
      CommonSteps.givenPropertyString(given);
    };

    // Create test block for each scenario
    test('Round earth', ({ given, when, then }) => {
      // Create steps that match the feature file
      background(given);

      given('I am normal', (world: World) => {
        // Utilize the world object to reference
        // data from step to step
        world.setGivenProp('earthShape', 'round');
      });

      when('I talk', (world: World) => {
        world.setResultProp('earthShape', world.getGiven().earthShape);
      });

      CommonSteps.thenResultPropertyStringShouldBe(then);
    });
```

## Additional Documentation

- [Configuration options](./docs/AdditionalConfiguration.md)
- [Running the examples](./docs/RunningTheExamples.md)
- [Using Docstrings](./docs/UsingDocstrings.md)
