Skip to content

Latest commit

 

History

History
1636 lines (1360 loc) · 54.8 KB

File metadata and controls

1636 lines (1360 loc) · 54.8 KB
slug description
10-minute-tutorial
Get started in 10 minutes

10-minute tutorial

In this quick tutorial you will learn how to:

  • Install Cucumber
  • Write your first scenario using the Gherkin syntax
  • Write your first step definition in language
  • Run Cucumber
  • Learn the basic workflow of Behaviour-Driven Development (BDD)

We'll use Cucumber to develop a small library that can figure out whether it's Friday yet.

  • A basic understanding of your chosen programming language and its standard tooling
  • Some experience using a terminal
  • Some experience using a text editor

Before we begin, you'll need the following:

- [Java SE](https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html) - A build tool. You can choose between: - [Maven](https://maven.apache.org/index.html) - version 3.3.1 or higher - [IntelliJ IDEA](https://www.jetbrains.com/idea/) (which will be used in this tutorial) - [IntelliJ IDEA Cucumber for Java plugin](https://plugins.jetbrains.com/plugin/7212-cucumber-for-java) - [Eclipse](https://www.eclipse.org/) (a good alternative if you don't use IntelliJ IDEA) - [Cucumber Eclipse](https://cucumber.github.io/cucumber-eclipse/) - [Java SE](https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html) (Java 9 and higher are not yet supported by Cucumber) - [Maven](https://maven.apache.org/index.html) - version 3.3.1 or higher - [IntelliJ IDEA](https://www.jetbrains.com/idea/) (which will be used in this tutorial) - [IntelliJ IDEA Cucumber for Java plugin](https://plugins.jetbrains.com/plugin/7212-cucumber-for-java) - [IntelliJ IDEA Kotlin plugin](https://plugins.jetbrains.com/plugin/6954-kotlin) - [Eclipse](https://www.eclipse.org/) (a good alternative if you don't use IntelliJ IDEA) - [Cucumber Eclipse](https://cucumber.github.io/cucumber-eclipse/) - [Kotlin Eclipse](https://github.com/JetBrains/kotlin-eclipse) - [Node.js](https://nodejs.org/) - A text editor
Open a terminal to verify that Node.js is installed properly:

```shell
node -v
npm -v
```

Both of these commands should print a version number.
- [Ruby](https://www.ruby-lang.org/) - [Bundler](https://bundler.io/) - A text editor
Open a terminal to verify that Ruby is installed properly:

```shell
ruby -v
bundle -v
```

Both of these commands should print a version number.

Create an empty Cucumber project

We'll start by creating a new project directory with the `cucumber-archetype` Maven plugin. Open a terminal, go to the directory where you want to create your project, and run the following command:
```shell
mvn archetype:generate                     \
"-DarchetypeGroupId=io.cucumber"           \
"-DarchetypeArtifactId=cucumber-archetype" \
"-DarchetypeVersion={{% version "cucumberjvm" %}}"                \
"-DgroupId=hellocucumber"                  \
"-DartifactId=hellocucumber"               \
"-Dpackage=hellocucumber"                  \
"-Dversion=1.0.0-SNAPSHOT"                 \
"-DinteractiveMode=false"
```

You should get something like the following result:
```shell
[INFO] Project created from Archetype in dir: [directory where you created the project]/cucumber
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```

Change into the directory that was just created by running the following command:

```shell
cd hellocucumber
```

Open the project in IntelliJ IDEA:

* **File -> Open... -> (Select the pom.xml)**
* Select **Open as Project**
To use Kotlin, we need to add it to our project:
* Add a directory named `kotlin` in your `src/test` directory and mark it as `Test Sources Root`.
In IntelliJ IDEA, you can do so by right-clicking on the `kotlin` directory and selecting **"Mark Directory as" > "Test Sources Root"**.
* Create the `hellocucumber` package inside the `kotlin` directory.
* Create a Kotlin class called `RunCucumberTest` inside the `hellocucumber` package. IntelliJ IDEA might tell you that Kotlin is not configured; click **"Configure"**.
Your `pom.xml` should now look like this:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>hellocucumber</groupId>
    <artifactId>hellocucumber</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <kotlin.version>1.8.10</kotlin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.cucumber</groupId>
                <artifactId>cucumber-bom</artifactId>
                <version>7.11.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>5.9.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit-platform-engine</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-test</artifactId>
            <version>${kotlin.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <source>src/test/java</source>
                                <source>src/test/kotlin</source>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <jvmTarget>1.8</jvmTarget>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>testCompile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```
* Copy the annotations from the `RunCucumberTest.java` class to the `RunCucumberTest.kt` class.
If you are using IntelliJ IDEA, it will offer to translate the Java code to Kotlin code. Otherwise, you'll have to write your own.

Your `RunCucumberTest.kt` class should now look like this:
```kotlin
package hellocucumber

import io.cucumber.junit.platform.engine.Constants
import org.junit.platform.suite.api.ConfigurationParameter
import org.junit.platform.suite.api.IncludeEngines
import org.junit.platform.suite.api.SelectClasspathResource
import org.junit.platform.suite.api.Suite

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("hellocucumber")
@ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME, value = "pretty")
class RunCucumberTest
```

* Now you can delete the `RunCucumberTest.java` class.
* Create a Kotlin class called `StepDefs` inside the `hellocucumber` package.
* Copy the import statements from `StepDefinitions.java` to `StepDefs.kt`; you'll need them later.
* Finally, delete the `StepDefinitions.java` class (or even the `java` directory).
We'll start by creating a new directory and an empty Node.js project.
```shell
mkdir hellocucumber
cd hellocucumber
npm init --yes
```

Add Cucumber as a development dependency:

```shell
npm install --save-dev @cucumber/cucumber
```

Open `package.json` in a text editor and change the `test` section so it looks like this:

```json
{
    "name": "hellocucumber",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "cucumber-js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@cucumber/cucumber": "^{{% version "cucumberjs" %}}"
    }
}
```

Prepare the file structure:

```shell
mkdir features
mkdir features/step_definitions
```

Create a file called `cucumber.json` at the root of your project and add the following
content:

```json
{
    "default": {
        "formatOptions": {
            "snippetInterface": "synchronous"
        }
    }
}
```

Also, create a file called `features/step_definitions/stepdefs.js` with the
following content:

```javascript
const assert = require('assert');
const { Given, When, Then } = require('@cucumber/cucumber');
```
We'll start by creating a new directory and an empty Ruby project.
```shell
mkdir hellocucumber
cd hellocucumber
```

Create a `Gemfile` with the following content:

```ruby
source "https://rubygems.org"

group :test do
    gem 'cucumber', '~> {{% version "cucumberruby" %}}'
    gem 'rspec', '~> {{% version "rspec" %}}'
end
```

Install Cucumber and prepare the file structure:

```shell
bundle install
cucumber --init
```

You now have a small project with Cucumber installed.

Verify your installation

To make sure everything works together correctly, let's run Cucumber.

```shell mvn test ``` ```shell npm test ``` ```shell cucumber ```

You should see something like the following:

```shell ------------------------------------------------------- T E S T S -------------------------------------------------------
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```
```shell 0 scenarios 0 steps 0m00.000s ``` ```shell 0 scenarios 0 steps 0m0.000s ```

Cucumber's output is telling us that it didn't find anything to run.

Write a scenario

When we do Behaviour-Driven Development with Cucumber we use concrete examples to specify what we want the software to do. Scenarios are written before production code. They start their life as an executable specification. As the production code emerges, scenarios take on a role as living documentation and automated tests.

:::tip[Example Mapping] Try running an Example Mapping workshop in your team to design examples together. :::

In Cucumber, an example is called a scenario. Scenarios are defined in .feature files, which are stored in the src/test/resources/hellocucumber features directory (or a subdirectory).

One concrete example would be that Sunday isn't Friday.

Create an empty file called src/test/resources/hellocucumber/is_it_friday_yet.feature features/is_it_friday_yet.feature with the following content:

Feature: Is it Friday yet?
  Everybody wants to know when it's Friday

  Scenario: Sunday isn't Friday
    Given today is Sunday
    When I ask whether it's Friday yet
    Then I should be told "Nope"

The first line of this file starts with the keyword Feature: followed by a name. It's a good idea to use a name similar to the file name.

The second line is a brief description of the feature. Cucumber does not execute this line because it's documentation.

The fourth line, Scenario: Sunday is not Friday is a scenario, which is a concrete example illustrating how the software should behave.

The last three lines starting with Given, When and Then are the steps of our scenario. This is what Cucumber will execute.

See scenario reported as undefined

Now that we have a scenario, we can ask Cucumber to execute it.

```shell mvn test ``` ```shell npm test ``` ```shell cucumber ```

Cucumber is telling us we have one undefined scenario and three undefined steps. It's also suggesting some snippets of code that we can use to define these steps:

```shell ------------------------------------------------------- T E S T S ------------------------------------------------------- Running hellocucumber.RunCucumberTest

Scenario: Sunday isn't Friday # hellocucumber/is_it_friday_yet.feature:4 Given today is Sunday When I ask whether it's Friday yet Then I should be told "Nope" [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.15 s <<< FAILURE! - in hellocucumber.RunCucumberTest [ERROR] Is it Friday yet?.Sunday isn't Friday Time elapsed: 0.062 s <<< ERROR! io.cucumber.junit.platform.engine.UndefinedStepException: The step 'today is Sunday' and 2 other step(s) are undefined. You can implement these steps using the snippet(s) below:

@Given("today is Sunday") public void today_is_sunday() { // Write code here that turns the phrase above into concrete actions throw new io.cucumber.java.PendingException(); } @When("I ask whether it's Friday yet") public void i_ask_whether_it_s_friday_yet() { // Write code here that turns the phrase above into concrete actions throw new io.cucumber.java.PendingException(); } @Then("I should be told {string}") public void i_should_be_told(String string) { // Write code here that turns the phrase above into concrete actions throw new io.cucumber.java.PendingException(); }

</Content>
<Content lang="javascript">
    ```shell
    UUU

    Warnings:

    1) Scenario: Sunday is not Friday # features/is_it_friday_yet.feature:4
       ? Given today is Sunday
           Undefined. Implement with the following snippet:

             Given('today is Sunday', function () {
               // Write code here that turns the phrase above into concrete actions
               return 'pending';
             });

       ? When I ask whether it's Friday yet
           Undefined. Implement with the following snippet:

             When('I ask whether it\'s Friday yet', function () {
               // Write code here that turns the phrase above into concrete actions
               return 'pending';
             });

       ? Then I should be told "Nope"
           Undefined. Implement with the following snippet:

             Then('I should be told {string}', function (string) {
               // Write code here that turns the phrase above into concrete actions
               return 'pending';
             });


    1 scenario (1 undefined)
    3 steps (3 undefined)
    0m00.000s
    ```
</Content>
<Content lang="ruby">
    ```shell
    Feature: Is it Friday yet?
    Everybody wants to know when it's Friday

    Scenario: Sunday is not Friday       # features/is_it_friday_yet.feature:4
      Given today is Sunday              # features/is_it_friday_yet.feature:5
      When I ask whether it's Friday yet # features/is_it_friday_yet.feature:6
      Then I should be told "Nope"       # features/is_it_friday_yet.feature:7

    1 scenario (1 undefined)
    3 steps (3 undefined)
    0m0.052s

    You can implement step definitions for undefined steps with these snippets:

    Given("today is Sunday") do
      pending # Write code here that turns the phrase above into concrete actions
    end

    When("I ask whether it's Friday yet") do
      pending # Write code here that turns the phrase above into concrete actions
    end

    Then("I should be told {string}") do |string|
      pending # Write code here that turns the phrase above into concrete actions
    end
    ```
</Content>

Copy each of the three snippets for the undefined steps and paste them into
<Content lang="java">`src/test/java/hellocucumber/StepDefinitions.java`</Content>
<Content lang="kotlin">`src/test/kotlin/hellocucumber/Stepdefs.kt`</Content>
<Content lang="javascript">`features/step_definitions/stepdefs.js`</Content>
<Content lang="ruby">`features/step_definitions/stepdefs.rb`</Content>.

<Content lang="kotlin">
    Unfortunately, Cucumber does not generate snippets in Kotlin. But fortunately IDEA can convert the Java code to Kotlin code for you. You might need to improve the translated code, to make it more idiomatic.
    You might also need to add the following import statements (if you hadn't already).

    Your `StepDefs.kt` file should now look like this:

    ```kotlin
    package hellocucumber

    import io.cucumber.java.PendingException
    import io.cucumber.java.en.Given
    import io.cucumber.java.en.When
    import io.cucumber.java.en.Then
    import static org.assertj.core.api.Assertions.assertThat;

    class StepDefs {
        @Given("today is Sunday")
        @Throws(Exception::class)
        fun today_is_Sunday() {
            // Write code here that turns the phrase above into concrete actions
            throw PendingException()
        }

        @When("I ask whether it's Friday yet")
        @Throws(Exception::class)
        fun i_ask_whether_it_s_Friday_yet() {
            // Write code here that turns the phrase above into concrete actions
            throw PendingException()
        }

        @Then("I should be told {string}")
        @Throws(Exception::class)
        fun i_should_be_told(arg1: String) {
            // Write code here that turns the phrase above into concrete actions
            throw PendingException()
        }
    }
    ```
</Content>

## See scenario reported as pending

Run Cucumber again. This time the output is a little different:

<Content lang="java">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # StepDefinitions.today_is_Sunday()
          io.cucumber.java.PendingException: TODO: implement me
        at hellocucumber.StepDefinitions.today_is_Sunday(StepDefinitions.java:14)
        at ?.today is Sunday(classpath:hellocucumber/is_it_friday_yet.feature:5)

        When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # StepDefinitions.i_should_be_told(String)

    Pending scenarios:
    hellocucumber/is_it_friday_yet.feature:4 # Sunday isn't Friday

    1 Scenarios (1 pending)
    3 Steps (2 skipped, 1 pending)
    0m0.188s

    io.cucumber.java.PendingException: TODO: implement me
        at hellocucumber.StepDefinitions.today_is_Sunday(StepDefinitions.java:13)
        at ?.today is Sunday(classpath:hellocucumber/is_it_friday_yet.feature:5)
    ```
</Content>
<Content lang="kotlin">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # StepDefs.today_is_Sunday()
          io.cucumber.java.PendingException: TODO: implement me
            at hellocucumber.StepDefs.today_is_Sunday(StepDefs.kt:14)
            at ✽.today is Sunday(hellocucumber/is_it_friday_yet.feature:5)

        When I ask whether it's Friday yet # StepDefs.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # StepDefs.i_should_be_told(String)

    1 Scenarios (1 pending)
    3 Steps (2 skipped, 1 pending)
    0m0.107s

    io.cucumber.java.PendingException: TODO: implement me
            at hellocucumber.StepDefs.today_is_Sunday(StepDefs.kt:14)
            at ✽.today is Sunday(hellocucumber/is_it_friday_yet.feature:5)

    Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.351 sec
    ```
</Content>
<Content lang="javascript">
    ```shell
    P--

    Warnings:

    1) Scenario: Sunday is not Friday # features/is_it_friday_yet.feature:4
       ? Given today is Sunday # features/step_definitions/stepdefs.js:3
           Pending
       - When I ask whether it's Friday yet # features/step_definitions/stepdefs.js:8
       - Then I should be told "Nope" # features/step_definitions/stepdefs.js:13

    1 Scenario (1 pending)
    3 steps (1 pending, 2 skipped)
    0m00.001s
    ```
</Content>
<Content lang="ruby">
    ```shell
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday is not Friday       # features/is_it_friday_yet.feature:4
        Given today is Sunday              # features/step_definitions/stepdefs.rb:1
          TODO (Cucumber::Pending)
          ./features/step_definitions/stepdefs.rb:2:in `"today is Sunday"'
          features/is_it_friday_yet.feature:5:in `Given today is Sunday'
        When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:5
        Then I should be told "Nope"       # features/step_definitions/stepdefs.rb:9

    1 scenario (1 pending)
    3 steps (2 skipped, 1 pending)
    0m0.073s
    ```
</Content>

Cucumber found our step definitions and executed them. They are currently marked as
*pending*, which means we need to make them do something useful.

## See scenario reported as failing

The next step is to do what the comments in the step definitions is telling us to do:

> Write code here that turns the phrase above into concrete actions

Try to use the same words in the code as in the steps.

:::tip[Ubiquitous language]
If the words in your steps originated from conversations during an
[Example Mapping](/docs/bdd/example-mapping) session, you're building a
[Ubiquitous Language](https://martinfowler.com/bliki/UbiquitousLanguage.html),
which we believe is a great way to make your production code and tests more understandable and easier to maintain.
:::

Change your step definition code to this:

<Content lang="java">
    ```java
    package hellocucumber;

    import io.cucumber.java.en.Given;
    import io.cucumber.java.en.When;
    import io.cucumber.java.en.Then;
    import static org.assertj.core.api.Assertions.assertThat;

    class IsItFriday {
        static String isItFriday(String today) {
            return null;
        }
    }

    public class StepDefinitions {
        private String today;
        private String actualAnswer;

        @Given("today is Sunday")
        public void today_is_Sunday() {
            today = "Sunday";
        }

        @When("I ask whether it's Friday yet")
        public void i_ask_whether_it_s_Friday_yet() {
            actualAnswer = IsItFriday.isItFriday(today);
        }

        @Then("I should be told {string}")
        public void i_should_be_told(String expectedAnswer) {
            assertThat(actualAnswer).isEqualTo(expectedAnswer);
        }
    }
    ```
</Content>
<Content lang="kotlin">
    ```kotlin
    package hellocucumber

    import io.cucumber.java.en.Then
    import io.cucumber.java.en.Given
    import io.cucumber.java.en.When
    import static org.assertj.core.api.Assertions.assertThat;


    fun isItFriday(today: String) = ""


    class StepDefs {
        private lateinit var today: String
        private lateinit var actualAnswer: String

        @Given("today is Sunday")
        fun today_is_Sunday() {
            today = "Sunday"
        }

        @When("I ask whether it's Friday yet")
        fun i_ask_whether_it_s_Friday_yet() {
            actualAnswer = isItFriday(today)
        }

        @Then("I should be told {string}")
        fun i_should_be_told(expectedAnswer: String) {
            assertThat(actualAnswer).isEqualTo(expectedAnswer)
        }
    }
    ```
</Content>
<Content lang="javascript">
    ```javascript
    const assert = require('assert');
    const { Given, When, Then } = require('@cucumber/cucumber');

    function isItFriday(today) {
      // We'll leave the implementation blank for now
    }

    Given('today is Sunday', function () {
      this.today = 'Sunday';
    });

    When('I ask whether it\'s Friday yet', function () {
      this.actualAnswer = isItFriday(this.today);
    });

    Then('I should be told {string}', function (expectedAnswer) {
      assert.strictEqual(this.actualAnswer, expectedAnswer);
    });
    ```
</Content>
<Content lang="ruby">
    ```ruby
    module FridayStepHelper
      def is_it_friday(day)
      end
    end
    World FridayStepHelper

    Given("today is Sunday") do
      @today = 'Sunday'
    end

    When("I ask whether it's Friday yet") do
      @actual_answer = is_it_friday(@today)
    end

    Then("I should be told {string}") do |expected_answer|
      expect(@actual_answer).to eq(expected_answer)
    end
    ```
</Content>

Run Cucumber again:

<Content lang="java">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # StepDefinitions.today_is_Sunday()
        When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # StepDefinitions.i_should_be_told(String)
          org.opentest4j.AssertionFailedError:
          expected: "Nope"
           but was: null
              at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
              at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
              at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
              at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
              at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
              at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)


    Failed scenarios:
    hellocucumber/is_it_friday_yet.feature:4 # Sunday isn't Friday

    1 Scenarios (1 failed)
    3 Steps (1 failed, 2 passed)
    0m0.404s
    ```
</Content>
<Content lang="kotlin">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # StepDefs.today_is_Sunday()
        When I ask whether it's Friday yet # StepDefs.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # StepDefs.i_should_be_told(String)
          org.opentest4j.AssertionFailedError:
          expected: "Nope"
           but was: null
              at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
              at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
              at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
              at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
              at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
              at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)
    ```
</Content>
<Content lang="javascript">
    ```shell
    ..F

    Failures:

    1) Scenario: Sunday is not Friday # features/is_it_friday_yet.feature:4
       ✔ Given today is Sunday # features/step_definitions/stepdefs.js:8
       ✔ When I ask whether it's Friday yet # features/step_definitions/stepdefs.js:12
       ✖ Then I should be told "Nope" # features/step_definitions/stepdefs.js:16
           AssertionError [ERR_ASSERTION]: undefined == 'Nope'
               at World.<anonymous> (/private/tmp/tutorial/hellocucumber/features/step_definitions/stepdefs.js:17:10)

    1 Scenario (1 failed)
    3 steps (1 failed, 2 passed)
    ```
</Content>
<Content lang="ruby">
    ```shell
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday is not Friday       # features/is_it_friday_yet.feature:4
        Given today is Sunday              # features/step_definitions/stepdefs.rb:4
        When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:8
        Then I should be told "Nope"       # features/step_definitions/stepdefs.rb:12

          expected: "Nope"
               got: nil

          (compared using ==)
           (RSpec::Expectations::ExpectationNotMetError)
          ./features/step_definitions/stepdefs.rb:13:in `"I should be told {string}"'
          features/is_it_friday_yet.feature:7:in `Then I should be told "Nope"'

    Failing Scenarios:
    cucumber features/is_it_friday_yet.feature:4 # Scenario: Sunday is not Friday

    1 scenario (1 failed)
    3 steps (1 failed, 2 passed)
    0m0.092s
    ```
</Content>

That's progress! The first two steps are passing, but the last one is failing.

## See scenario reported as passing

Let's do the minimum we need to make the scenario pass. In this case, that means making our <Term>stepdef-body</Term> return `Nope`:

<Content lang="java">
    ```java
    static String isItFriday(String today) {
        return "Nope";
    }
    ```
</Content>
<Content lang="kotlin">
    ```kotlin
    fun isItFriday(today: String) = "Nope"
    ```
</Content>
<Content lang="javascript">
    ```javascript
    function isItFriday(today) {
        return 'Nope';
    }
    ```
</Content>
<Content lang="ruby">
    ```ruby
    def is_it_friday(day)
      'Nope'
    end
    ```
</Content>

Run Cucumber again:

<Content lang="java">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # StepDefinitions.today_is_Sunday()
        When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # StepDefinitions.i_should_be_told(String)

    1 Scenarios (1 passed)
    3 Steps (3 passed)
    0m0.255s
    ```
</Content>
<Content lang="kotlin">
    ```shell
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running hellocucumber.RunCucumberTest
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
        Given today is Sunday              # Stepdefs.today_is_Sunday()
        When I ask whether it's Friday yet # Stepdefs.i_ask_whether_it_s_Friday_yet()
        Then I should be told "Nope"       # Stepdefs.i_should_be_told(String)

    1 Scenarios (1 passed)
    3 Steps (3 passed)
    0m0.255s
    ```
</Content>
<Content lang="javascript">
    ```shell
    ...

    1 scenario (1 passed)
    3 steps (3 passed)
    0m00.003s
    ```
</Content>
<Content lang="ruby">
    ```shell
    Feature: Is it Friday yet?
      Everybody wants to know when it's Friday

      Scenario: Sunday is not Friday       # features/is_it_friday_yet.feature:4
        Given today is Sunday              # features/step_definitions/stepdefs.rb:5
        When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:9
        Then I should be told "Nope"       # features/step_definitions/stepdefs.rb:13

    1 scenario (1 passed)
    3 steps (3 passed)
    0m0.066s
    ```
</Content>

Congratulations! You've got your first green Cucumber scenario.

## Add another failing test

The next thing to test for would be that we also get the correct result when it *is* Friday.

Update the `is_it_friday_yet.feature` file:

```gherkin
Feature: Is it Friday yet?
  Everybody wants to know when it's Friday

  Scenario: Sunday isn't Friday
    Given today is Sunday
    When I ask whether it's Friday yet
    Then I should be told "Nope"

  Scenario: Friday is Friday
    Given today is Friday
    When I ask whether it's Friday yet
    Then I should be told "TGIF"

We'll need to add a step definition to set today to "Friday":

```java @Given("today is Friday") public void today_is_Friday() { today = "Friday"; } ``` ```kotlin @Given("today is Friday") fun today_is_Friday() { today = "Friday" } ``` ```javascript Given('today is Friday', function () { this.today = 'Friday'; }); ``` ```ruby Given("today is Friday") do @today = 'Friday' end ```

When we run this test, it will fail.

```shell ------------------------------------------------------- T E S T S ------------------------------------------------------- Running hellocucumber.RunCucumberTest Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
    Given today is Sunday              # StepDefinitions.today_is_Sunday()
    When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
    Then I should be told "Nope"       # StepDefinitions.i_should_be_told(String)

  Scenario: Friday is Friday           # hellocucumber/is_it_friday_yet.feature:9
    Given today is Friday              # StepDefinitions.today_is_Friday()
    When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
    Then I should be told "TGIF"       # StepDefinitions.i_should_be_told(String)
      org.opentest4j.AssertionFailedError:
        expected: "TGIF"
         but was: "Nope"
            at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
            at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
            at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
            at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)


Failed scenarios:
hellocucumber/is_it_friday_yet.feature:9 # Friday is Friday

2 Scenarios (1 failed, 1 passed)
6 Steps (1 failed, 5 passed)
0m0.085s

org.opentest4j.AssertionFailedError:
  expected: "TGIF"
   but was: "Nope"
      at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
      at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
      at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
      at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)
```
```shell Running hellocucumber.RunCucumberTest Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # hellocucumber/isitfriday.feature:4
    Given today is Sunday              # StepDefs.today_is_Sunday()
    When I ask whether it's Friday yet # StepDefs.i_ask_whether_it_s_Friday_yet()
    Then I should be told "Nope"       # StepDefs.i_should_be_told(String)

  Scenario: Friday is Friday           # hellocucumber/isitfriday.feature:9
    Given today is Friday              # StepDefs.today_is_Friday()
    When I ask whether it's Friday yet # StepDefs.i_ask_whether_it_s_Friday_yet()
    Then I should be told "TGIF"       # StepDefs.i_should_be_told(String)
      org.opentest4j.AssertionFailedError:
        expected: "TGIF"
         but was: "Nope"
            at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
            at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
            at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
            at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)

Failed scenarios:
hellocucumber/isitfriday.feature:9 # Friday is Friday

2 Scenarios (1 failed, 1 passed)
6 Steps (1 failed, 5 passed)
0m0.100s

org.opentest4j.AssertionFailedError:
  expected: "TGIF"
   but was: "Nope"
      at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
      at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
      at io.cucumber.skeleton.StepDefinitions.I_have_cukes_in_my_belly(StepDefinitions.java:12)
      at ✽.I have 42 cukes in my belly(classpath:io/cucumber/skeleton/belly.feature:4)

```
```shell .....F
Failures:

1) Scenario: Friday is Friday # features/is_it_friday_yet.feature:9
   ✔ Given today is Friday # features/step_definitions/stepdefs.js:8
   ✔ When I ask whether it's Friday yet # features/step_definitions/stepdefs.js:16
   ✖ Then I should be told "TGIF" # features/step_definitions/stepdefs.js:20
       AssertionError [ERR_ASSERTION]: 'Nope' == 'TGIF'
           + expected - actual

           -Nope
           +TGIF

           at World.<anonymous> (/private/tmp/tutorial/hellocucumber/features/step_definitions/stepdefs.js:21:10)

2 scenarios (1 failed, 1 passed)
6 steps (1 failed, 5 passed)
```
```shell Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # features/is_it_friday_yet.feature:4
    Given today is Sunday              # features/step_definitions/stepdefs.rb:12
    When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:16
    Then I should be told "Nope"       # features/step_definitions/stepdefs.rb:20

  Scenario: Friday is Friday           # features/is_it_friday_yet.feature:9
    Given today is Friday              # features/step_definitions/stepdefs.rb:8
    When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:16
    Then I should be told "TGIF"       # features/step_definitions/stepdefs.rb:20

      expected: "TGIF"
           got: "Nope"

      (compared using ==)
       (RSpec::Expectations::ExpectationNotMetError)
      ./features/step_definitions/stepdefs.rb:21:in `"I should be told {string}"'
      features/is_it_friday_yet.feature:12:in `Then I should be told "TGIF"'

Failing Scenarios:
cucumber features/is_it_friday_yet.feature:9 # Scenario: Friday is Friday

2 scenarios (1 failed, 1 passed)
6 steps (1 failed, 5 passed)
```

That is because we haven't implemented the logic yet! Let's do that next.

Make it pass

We should update our statement to actually evaluate whether or not today is equal to "Friday".

```java static String isItFriday(String today) { return "Friday".equals(today) ? "TGIF" : "Nope"; } ``` ```kotlin fun isItFriday(today: String) = if (today == "Friday") "TGIF" else "Nope" ``` ```javascript function isItFriday(today) { if (today === "Friday") { return "TGIF"; } else { return "Nope"; } } ``` ```ruby def is_it_friday(day) if day == 'Friday' 'TGIF' else 'Nope' end end ```

Run Cucumber again:

```shell ------------------------------------------------------- T E S T S ------------------------------------------------------- Running hellocucumber.RunCucumberTest Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
    Given today is Sunday              # StepDefinitions.today_is_Sunday()
    When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
    Then I should be told "Nope"       # StepDefinitions.i_should_be_told(String)

  Scenario: Friday is Friday           # hellocucumber/is_it_friday_yet.feature:9
    Given today is Friday              # StepDefinitions.today_is_Friday()
    When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet()
    Then I should be told "TGIF"       # StepDefinitions.i_should_be_told(String)

2 Scenarios (2 passed)
6 Steps (6 passed)
0m0.255s
```
```shell ------------------------------------------------------- T E S T S ------------------------------------------------------- Running hellocucumber.RunCucumberTest Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # hellocucumber/is_it_friday_yet.feature:4
    Given today is Sunday              # Stepdefs.today_is_Sunday()
    When I ask whether it's Friday yet # Stepdefs.i_ask_whether_it_s_Friday_yet()
    Then I should be told "Nope"       # Stepdefs.i_should_be_told(String)

  Scenario: Friday is Friday           # hellocucumber/is_it_friday_yet.feature:9
    Given today is Friday              # Stepdefs.today_is_Friday()
    When I ask whether it's Friday yet # Stepdefs.i_ask_whether_it_s_Friday_yet()
    Then I should be told "TGIF"       # Stepdefs.i_should_be_told(String)

2 Scenarios (2 passed)
6 Steps (6 passed)
0m0.255s
```
```shell ...... 2 scenarios (2 passed) 6 steps (6 passed) 0m00.002s ``` ```shell Feature: Is it Friday yet? Everybody wants to know when it's Friday
  Scenario: Sunday isn't Friday        # features/is_it_friday_yet.feature:4
    Given today is Sunday              # features/step_definitions/stepdefs.rb:8
    When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:17
    Then I should be told "Nope"       # features/step_definitions/stepdefs.rb:22

  Scenario: Friday is Friday           # features/is_it_friday_yet.feature:9
    Given today is Friday              # features/step_definitions/stepdefs.rb:12
    When I ask whether it's Friday yet # features/step_definitions/stepdefs.rb:17
    Then I should be told "TGIF"       # features/step_definitions/stepdefs.rb:22

2 scenarios (2 passed)
6 steps (6 passed)
0m0.040s
```

Using variables and examples

So, we all know that there are more days in the week than just Sunday and Friday. Let's update our scenario to use variables and evaluate more possibilities. We'll use variables and examples to evaluate Friday, Sunday, and anything else!

Update the is_it_friday_yet.feature file. Notice how we go from Scenario to Scenario Outline when we start using multiple Examples.

Feature: Is it Friday yet?
  Everybody wants to know when it's Friday

  Scenario Outline: Today is or is not Friday
    Given today is "<day>"
    When I ask whether it's Friday yet
    Then I should be told "<answer>"

  Examples:
    | day            | answer |
    | Friday         | TGIF   |
    | Sunday         | Nope   |
    | anything else! | Nope   |

We need to replace the step definitions for today is Sunday and today is Friday with one step definition that takes the value of <day> as a String. Update the step definitions as follows:

```java package hellocucumber;

import io.cucumber.java.en.Given; import io.cucumber.java.en.When; import io.cucumber.java.en.Then; import static org.assertj.core.api.Assertions.assertThat;

class IsItFriday { static String isItFriday(String today) { return "Friday".equals(today) ? "TGIF" : "Nope"; } }

public class Stepdefs { private String today; private String actualAnswer;

@Given("today is {string}")
public void today_is(String today) {
    this.today = today;
}

@When("I ask whether it's Friday yet")
public void i_ask_whether_it_s_Friday_yet() {
    actualAnswer = IsItFriday.isItFriday(today);
}

@Then("I should be told {string}")
public void i_should_be_told(String expectedAnswer) {
    assertThat(actualAnswer).isEqualTo(expectedAnswer);
}

}

</Content>
<Content lang="kotlin">
```kotlin
package hellocucumber

import io.cucumber.java.en.Then
import io.cucumber.java.en.Given
import io.cucumber.java.en.When
import static org.assertj.core.api.Assertions.assertThat

fun isItFriday(today: String) = if (today == "Friday") "TGIF" else "Nope"


class StepDefs {
    private lateinit var today: String
    private lateinit var actualAnswer: String

    @Given("today is {string}")
    fun today_is(today: String) {
        this.today = today
    }

    @When("I ask whether it's Friday yet")
    fun i_ask_whether_it_s_Friday_yet() {
        actualAnswer = isItFriday(today)
    }

    @Then("I should be told {string}")
    fun i_should_be_told(expectedAnswer: String) {
        assertThat(actualAnswer).isEqualTo(expectedAnswer)
    }
}
```javascript const assert = require('assert'); const { Given, When, Then } = require('@cucumber/cucumber');

function isItFriday(today) { if (today === "Friday") { return "TGIF"; } else { return "Nope"; } }

Given('today is {string}', function (givenDay) { this.today = givenDay; });

When('I ask whether it's Friday yet', function () { this.actualAnswer = isItFriday(this.today); });

Then('I should be told {string}', function (expectedAnswer) { assert.strictEqual(this.actualAnswer, expectedAnswer); });

</Content>
<Content lang="ruby">
```ruby
module FridayStepHelper
  def is_it_friday(day)
    if day == 'Friday'
      'TGIF'
    else
      'Nope'
    end
  end
end

World FridayStepHelper

Given("today is {string}") do |given_day|
  @today = given_day
end

When("I ask whether it's Friday yet") do
  @actual_answer = is_it_friday(@today)
end

Then("I should be told {string}") do |expected_answer|
  expect(@actual_answer).to eq(expected_answer)
end

Run Cucumber again:

```shell ------------------------------------------------------- T E S T S ------------------------------------------------------- Running hellocucumber.RunCucumberTest Feature: Is it Friday yet? Everybody wants to know when it's Friday

Scenario Outline: Today is or is not Friday # hellocucumber/is_it_friday_yet.feature:4 Given today is "" When I ask whether it's Friday yet Then I should be told ""

Examples:

Scenario Outline: Today is or is not Friday # hellocucumber/is_it_friday_yet.feature:11 Given today is "Friday" # StepDefinitions.today_is(String) When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet() Then I should be told "TGIF" # StepDefinitions.i_should_be_told(String)

Scenario Outline: Today is or is not Friday # hellocucumber/is_it_friday_yet.feature:12 Given today is "Sunday" # StepDefinitions.today_is(String) When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet() Then I should be told "Nope" # StepDefinitions.i_should_be_told(String)

Scenario Outline: Today is or is not Friday # hellocucumber/is_it_friday_yet.feature:13 Given today is "anything else!" # StepDefinitions.today_is(String) When I ask whether it's Friday yet # StepDefinitions.i_ask_whether_it_s_Friday_yet() Then I should be told "Nope" # StepDefinitions.i_should_be_told(String)

3 Scenarios (3 passed) 9 Steps (9 passed) 0m0.255s

</Content>
<Content lang="javascript">
```shell
.........

3 scenarios (3 passed)
9 steps (9 passed)
0m00.001s
```shell Feature: Is it Friday yet? Everybody wants to know when it's Friday

Scenario Outline: Today is or is not Friday # features/is_it_friday_yet.feature:4 Given today is # features/is_it_friday_yet.feature:5 When I ask whether it's Friday yet # features/is_it_friday_yet.feature:6 Then I should be told # features/is_it_friday_yet.feature:7

Examples:
  | day              | answer |
  | "Friday"         | "TGIF" |
  | "Sunday"         | "Nope" |
  | "anything else!" | "Nope" |

3 scenarios (3 passed) 9 steps (9 passed) 0m0.021s

</Content>

## Refactoring

Now that we have working code, we should do some refactoring:

* We should move the `isItFriday` <Term>stepdef-body</Term> out from the test code into production code.
* We could at some point extract helper methods from our step definition, for <Term>stepdef-body</Term>s we use in several places.

## Summary

In this brief tutorial you've seen how to install Cucumber, how to follow
the BDD process to develop a <Term>stepdef-body</Term>, and how to use that <Term>stepdef-body</Term> to evaluate multiple scenarios!