VOOZH about

URL: https://cucumber.io/docs/cucumber/api/?lang=java

⇱ Cucumber reference | Cucumber


Skip to main content

Cucumber can be used to implement automated tests based on scenarios described in your Gherkin feature files.

Step arguments

In the example given in step definitions, Cucumber extracts the text 48 from the step, converts it to an int and passes it as an argument to the method.

The number of parameters in the method has to match the number of capture groups in the expression. (If there is a mismatch, Cucumber will throw an error).

Data tables

Data tables from Gherkin can be accessed by using the DataTable object as the last parameter in a step definition.

  • Java
  • Kotlin
  • Scala
  • JavaScript

Depending on the table shape, the following collections can be also used as the last parameter in a step definition. This conversion is done by Cucumber.

List<List<String>> table
List<Map<String,String>> table
Map<String,String> table
Map<String,List<String>> table
Map<String,Map<String,String>> table

In addition to collections of String, Integer, Float, BigInteger and BigDecimal. Byte, Short, Long and Double are also supported by Cucumber. By registering a data table type it is also possible to support other types. See cucumber-jvm data-table-type for more.

Depending on the table shape, the following collections can be also used as the last parameter in a step definition. This conversion is done by Cucumber.

List<List<String>> table
List<Map<String,String>> table
Map<String,String> table
Map<String,List<String>> table
Map<String,Map<String,String>> table

In addition to collections of String, Integer, Float, BigInteger and BigDecimal. Byte, Short, Long and Double are also supported by Cucumber. By registering a data table type it is also possible to support other types. See cucumber-jvm data-table-type for more.

Depending on the table shape, the following collections can be also used as the last parameter in a step definition. This conversion is done by Cucumber.

List<List<String>> table
List<Map<String,String>> table
Map<String,String> table
Map<String,List<String>> table
Map<String,Map<String,String>> table

In addition to collections of String, Integer, Float, BigInteger and BigDecimal. Byte, Short, Long and Double are also supported by Cucumber. By registering a data table type it is also possible to support other types. See cucumber-jvm data-table-type for more.

The simplest way to pass a list of strings to a step definition is to use a data table:

Given the following animals:
| cow |
| horse |
| sheep |
  • Java
  • Kotlin
  • Scala
  • JavaScript

Declare the argument as a List<String> but don't define any capture group in the expression.

Annotated method style:

@Given("the following animals:")
publicvoidthe_following_animals(List<String> animals){
}

In this case, the DataTable is automatically flattened to a list of strings by Cucumber (using DataTable.asList(String.class)) before invoking the step definition.

Declare the argument as a List<String> but don't define any capture group in the expression.

Annotated method style:

@Given("the following animals:")
funthe_following_animals(animals: List<String>){
}

In this case, the DataTable is automatically flattened to a list of strings by Cucumber (using DataTable.asList(String.class)) before invoking the step definition.

Given("the following animals:"){ animals: java.util.List[String]=>
}

In this case, the DataTable is automatically flattened to a list of strings by Cucumber (using DataTable.asList(String.class)) before invoking the step definition.

For now, Cucumber Scala does not support using Scala collection types, see this issue.

For an example of using data tables in JavaScript, go here

Steps

A step is analogous to a method call or function invocation.

For example:

Given I have 93 cucumbers in my belly

In this step, you're "calling" the above step definition with one argument: the value 93.

Steps are declared in your *.feature files.

Matching steps

  1. Cucumber matches a step against a step definition's Regexp
  2. Cucumber gathers any capture groups or variables
  3. Cucumber passes them to the step definition's method and executes it

Recall that step definitions start with a preposition or an adverb (Given, When, Then, And, But).

All step definitions are loaded (and defined) before Cucumber starts to execute the plain text in the feature file.

Once execution begins, for each step, Cucumber will look for a registered step definition with a matching Regexp. If it finds one, it will execute it, passing all capture groups and variables from the Regexp as arguments to the method.

The specific preposition/adverb used has no significance when Cucumber is registering or looking up step definitions.

Also, check out multiline step arguments for more info on how to pass entire tables or bigger strings to your step definitions.

Step results

Each step can have one of the following results:

Success

When Cucumber finds a matching step definition it will execute it. If the block in the step definition doesn't raise an error, the step is marked as successful (green). Anything you return from a step definition has no significance whatsoever.

Undefined

When Cucumber can't find a matching step definition, the step gets marked as undefined (yellow), and all subsequent steps in the scenario are skipped.

Pending

When a step definition's method invokes the pending method, the step is marked as pending (yellow, as with undefined ones), indicating that you have work to do.

Failed Steps

When a step definition's method is executed and raises an error, the step is marked as failed (red). What you return from a step definition has no significance whatsoever.

Returning null, false or some other falsy value in your programming language will not cause a step definition to fail.

Skipped

Steps that follow undefined, pending, or failed steps are never executed, even if there is a matching step definition. These steps are marked as skipped (cyan).

Ambiguous

Step definitions have to be unique for Cucumber to know what to execute. If more than one step definition is matched for the same step, Cucucmber can't resolve the ambiguity on its own. The behaviour varies a bit between implementations:

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby
Cucumber will throw an AmbiguousStepDefinitionsException.
Cucumber will throw an AmbiguousStepDefinitionsException.
Cucumber will throw an AmbiguousStepDefinitionsException.
Cucumber will report an ambiguous result status.
Cucumber will raise a Cucumber::Ambiguous error.

Hooks

Hooks are blocks of code that can run at various points in the Cucumber execution cycle. They are typically used for setup and teardown of the environment before and after each scenario.

Where a hook is defined has no impact on what scenarios or steps it is run for. If you want more fine-grained control, you can use conditional hooks.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby
You can declare hooks in any class.
You can declare hooks in any class.
You can declare hooks in any class, trait or object.
You can declare hooks in your features/support/env.js file, or any other file under the features/support directory (for example, in a file called features/support/hooks.js).
You can declare hooks in your features/support/env.rb file, or any other file under the features/support directory (for example, in a file called support/hooks.rb).

Scenario hooks

Scenario hooks run for every scenario.

Before

Before hooks run before the first step of each scenario.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@Before
publicvoiddoSomethingBefore(){
}

Lambda style:

Before(()->{
});

Lambda style:

Before { scenario: Scenario ->
// doSomething
}
Before { scenario: Scenario =>
// doSomething
}
// Import the Before function
const{Before}=require('@cucumber/cucumber')

Before(asyncfunction(){
})
Avoid arrow functions

Arrow functions (() => {}) bind this to the current context, which prevents sharing state between hooks and step definitions.

Before do
# Do something before each scenario
end
Think twice before you use Before

Whatever happens in a Before hook is invisible to people who only read the features. You should consider using a background as a more explicit alternative, especially if the setup should be readable by non-technical people. Only use a Before hook for low-level logic such as starting a browser or deleting data from a database.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

You can specify an explicit order for hooks if you need to.

Annotated method style:

@Before(order =10)
publicvoiddoSomething(){
// Do something before each scenario
}

Lambda style:

Before(10,()->{
// Do something before each scenario
});

You can specify an explicit order for hooks if you need to.

Before(10){ scenario: Scenario ->
// Do something before each scenario
}
Using Kotlin named objects or companion objects

If @BeforeAll, @AfterAll etc. are used in Kotlin named objects or companion objects an io.cucumber.java.InvalidMethodSignatureException will be thrown, as Kotlin will create a class MyStepDefinitions$Companion which has non-static methods. Read more about it here.

The @JvmStatic annotation does not prevent this behaviour of Kotlin; it adds the static methods to MyStepDefinitionsMethod only.

Consequently, Cucumber will detect the static methods in MyStepDefinitions class, as well as the non-static methods in MyStepDefinitions$Companion class and will complain about the second one.

As a solution to this problem, use package level functions - this is, without companion objects.

package io.cucumber.example

import io.cucumber.java.AfterAll
import io.cucumber.java.BeforeAll

@BeforeAll
funbeforeAll(){
println("before all")
}

@AfterAll
funafterAll(){
println("after all")
}

You can specify an explicit order for hooks if you need to.

Before(10){ scenario: Scenario =>
// Do something before each scenario
}
Before hooks run in the same order in which they are declared.
Before hooks run in the same order in which they are declared.

After

After hooks run after the last step of each scenario, even when the step result is failed, undefined, pending, or skipped.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@After
publicvoiddoSomethingAfter(Scenario scenario){
// Do something after after scenario
}

Lambda style:

After((Scenario scenario)->{
});

Lambda style:

After { scenario: Scenario ->
// doSomething
}
After { scenario: Scenario =>
// doSomething
}
After(asyncfunction(scenario){
})
After do|scenario|
end

Here is an example in which we exit at the first failure (which could be useful in some cases like Continuous Integration, where fast feedback is important).

After do|s|
# Tell Cucumber to quit after this scenario is done - if it failed.
Cucumber.wants_to_quit =trueif s.failed?
end

The scenario parameter is optional. If you use it, you can inspect the status of the scenario.

For example, you can take a screenshot for failed scenarios and embed them in Cucumber's report(s); see the browser automation page for an example on how to do so.

Around

Ruby only

This section is only applicable to the Ruby implementation of Cucumber.

Around hooks will run "around" a scenario. This can be used to wrap the execution of a scenario in a block. The Around hook receives a Scenario object and a block (Proc) object. The scenario will be executed when you invoke block.call.

The following example will cause scenarios tagged with @fast to fail if the execution takes longer than 0.5 seconds:

Around('@fast')do|scenario, block|
Timeout.timeout(0.5)do
block.call
end
end

Step hooks

Step hooks are invoked before and after a step. The hooks have "invoke around" semantics, meaning that if a BeforeStep hook is executed the AfterStep hooks will also be executed regardless of the result of the step. If a step did not pass, the following step and its hooks will be skipped.

BeforeStep

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@BeforeStep
publicvoiddoSomethingBeforeStep(Scenario scenario){
}

Lambda style:

BeforeStep((Scenario scenario)->{

});

Lambda style:

BeforeStep { scenario: Scenario ->
// doSomething
}
BeforeStep { scenario: Scenario =>
// doSomething
}
BeforeStep(asyncfunction({pickle, pickleStep, gherkinDocument, testCaseStartedId, testStepId}){
// doSomething
})

BeforeStep({tags:"@foo"},asyncfunction(){
// apply this hook to only specific scenarios
})
Cucumber-Ruby does not support BeforeStep hooks.

AfterStep

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@AfterStep
publicvoiddoSomethingAfterStep(Scenario scenario){
}

Lambda style:

AfterStep((Scenario scenario)->{
});

Lambda style:

AfterStep { scenario: Scenario ->
// doSomething
}
AfterStep { scenario: Scenario =>
// doSomething
}
AfterStep(asyncfunction({pickle, pickleStep, gherkinDocument, result, testCaseStartedId, testStepId}){
// doSomething
})
AfterStep do|scenario|
end

Conditional hooks

Hooks can be conditionally selected for execution based on the tags of the scenario. To run a particular hook only for certain scenarios, you can associate a hook with a tag expression.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@After("@browser and not @headless")
publicvoiddoSomethingAfter(Scenario scenario){
}

Lambda style:

After("@browser and not @headless",(Scenario scenario)->{
});

Lambda style:

After(arrayOf("@browser and not @headless")){ scenario: Scenario ->
driver.quit()
}
After("@browser and not @headless"){ scenario: Scenario =>

}
Before({tags:'@browser and not @headless'},asyncfunction(){
})
Before('@browser and not @headless')do
end

See more documentation on tags.

Global hooks

Global hooks will run once before any scenario is run or after all scenarios have been run.

BeforeAll

Each BeforeAll hook will run before any scenario is run.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@BeforeAll
publicstaticvoidbeforeAll(){
// Runs before all scenarios
}
BeforeAll {
// doSomething
}
BeforeAll {
// doSomething
}
const{BeforeAll}=require('@cucumber/cucumber');

BeforeAll(asyncfunction(){
// perform some shared setup
});

Put the code at the top-level in your env.rb file (or any other file under features/support directory).

BeforeAll do
# Do something before any scenario is executed
end

AfterAll

Each AfterAll hook will run after all scenarios have been executed.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Annotated method style:

@AfterAll
publicstaticvoidafterAll(){
// Runs after all scenarios
}
AfterAll {
// doSomething
}
AfterAll {
// doSomething
}
const{AfterAll}=require('@cucumber/cucumber');

AfterAll(asyncfunction(){
// perform some shared setup
});
AfterAll do
# Do something after all scenarios have been executed
end

InstallPlugin

Ruby only

This section is only applicable to the Ruby implementation of Cucumber.

You may provide an InstallPlugin hook that will be run after Cucumber has been configured. The block you provide will be passed on to Cucumber's configuration (an instance of Cucumber::Cli::Configuration), and a wrapper to some cucumber internals as a registry.

InstallPlugin do|config, registry|
puts "Features dwell in #{config.feature_dirs}"
end

This hook will run only once: after support has been loaded, and before any features are loaded.

You can use this hook to extend Cucumber. For example, you could affect how features are loaded, or register custom formatters programmatically. cucumber-wire is a good example of how to use InstallPlugin and what a Cucumber plugin can do.

Tags

Tags are a great way to organise your features and scenarios.

They can be used for two purposes:

Consider the following example:

@billing
Feature: Verify billing

@important
Scenario: Missing product description
Given hello

Scenario: Several products
Given hello

A feature or scenario can have as many tags as you like. Separate them with spaces:

@billing@bicker@annoy
Feature: Verify billing

Tags can be placed above the following Gherkin elements:

  • Feature
  • Rule
  • Scenario
  • Scenario Outline
  • Examples

In Scenario Outline, you can use tags on different sets of examples like below:

Scenario Outline: Steps will run conditionally if tagged
Given user is logged in
When user clicks <link>
Then user will be logged out

@mobile
Examples:
| link |
| logout link on mobile |

@desktop
Examples:
| link |
| logout link on desktop |

It is not possible to place tags above Background or steps (Given, When, Then, And and But).

Tag inheritance

Tags are inherited by child elements. So, tags that are placed above a Feature will be inherited by Rule, Scenario, Scenario Outline, or Examples. And similarly tags that are placed above a Scenario Outline will be inherited by Examples.

Running a subset of scenarios

You can tell Cucumber to only run scenarios with a particular tag:

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

For JUnit 5 see the cucumber-junit-platform-engine documentation

For JUnit 4 and TestNG using a JVM system property:

mvn test -Dcucumber.filter.tags="@smoke and @fast"

Or an environment variable:

# Linux / OS X:
CUCUMBER_FILTER_TAGS="@smoke and @fast" mvn test

# Windows:
set CUCUMBER_FILTER_TAGS="@smoke and @fast"
mvn test

Or annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="@smoke and @fast")

For JUnit 5 see the cucumber-junit-platform-engine documentation

For JUnit 4 and TestNG using a JVM system property:

mvn test -Dcucumber.filter.tags="@smoke and @fast"

Or an environment variable:

# Linux / OS X:
CUCUMBER_FILTER_TAGS="@smoke and @fast" mvn test

# Windows:
set CUCUMBER_FILTER_TAGS="@smoke and @fast"
mvn test

Or annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="@smoke and @fast")

For JUnit 5 see the cucumber-junit-platform-engine documentation

For JUnit 4 and TestNG using a JVM system property:

mvn test -Dcucumber.filter.tags="@smoke and @fast"

Or an environment variable:

# Linux / OS X:
CUCUMBER_FILTER_TAGS="@smoke and @fast" mvn test

# Windows:
set CUCUMBER_FILTER_TAGS="@smoke and @fast"
mvn test

Or annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="@smoke and @fast")
# You can omit the quotes if the expression is a single tag
./node_modules/.bin/cucumber.js --tags "@smoke and @fast"
# You can omit the quotes if the expression is a single tag
cucumber --tags "@smoke and @fast"

Ignoring a subset of scenarios

You can tell Cucumber to ignore scenarios with a particular tag:

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

By annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="not @smoke")

By annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="not @smoke")

By annotating your JUnit 4/TestNG runner class:

@CucumberOptions(tags ="not @smoke")
# You can omit the quotes if the expression is a single tag
./node_modules/.bin/cucumber.js --tags "not @smoke"
# You can omit the quotes if the expression is a single tag
cucumber --tags "not @smoke"
Filtering by line

Another way to run a subset of scenarios is to use the file.feature:line pattern or the --scenario option.

Tag expressions

A tag expression is an infix boolean expression. Below are some examples:

ExpressionDescription
@fastScenarios tagged with @fast
@wip and not @slowScenarios tagged with @wip that aren't also tagged with @slow
@smoke and @fastScenarios tagged with both @smoke and @fast
@gui or @databaseScenarios tagged with either @gui or @database

For even more advanced tag expressions you can use parenthesis for clarity, or to change operator precedence:

(@smoke or @ui) and (not @slow)

Using tags for documentation

Your imagination is the only limitation when it comes to using tags for documentation.

Tags can refer to IDs in external systems such as requirement management tools, issue trackers or test management tools:

@BJ-x98.77@BJ-z12.33
Feature: Convert transaction

You can use a custom Cucumber reporting plugin that will turn tags into links pointing to documents in your external tool.

Development process

Another creative way to use tags is to keep track of where in the development process a certain feature is:

@qa_ready
Feature: Index projects

@wip

Rails only

This section is only applicable to the Rails implementation of Cucumber.

As distributed, Cucumber-Rails builds a Rake task that recognizes the @wip tag. However, any string may be used as a tag and any scenario or entire feature can have multiple tags associated with it.

The default profile contained in the distributed config/cucumber.yml contains these lines:

<%
. . .
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
%>
default: <%= std_opts %> features
. . .

Note the trailing option --tags ~@wip. Cucumber provides for negating tags by prefacing the --tags argument with a tilde character (~). This tells Cucumber to not process features and scenarios with this tag. If you do not specify a different profile (cucumber -p profilename), then the default profile will be used. If the default profile is used, then the --tags ~@wip will cause Cucumber to skip any scenario with this tag. This will override the --tags=@authen option passed in the command line, and so you will see this:

cucumber --tags=@authentication
Using the default profile...

0 scenarios
0 steps
0m0.000s

Since version 0.6.0, one can no longer overcome this default setting by adding the --tags=@wip to the Cucumber argument list on the command line, because now all --tags options are combined with "and" logic. Thus, the combination of --tags @wip and --tags ~@wip fails everywhere.

You either must create a special profile in config/cucumber.yml to deal with this, or alter the default profile to suit your needs.

The @wip tags are a special case. If any scenario tagged as @wip passes all of its steps without error, and the --wip option is also passed, Cucumber reports the run as failing (because Scenarios that are marked as a work in progress are not supposed to pass!)

Note as well that the --strict and --wip options are mutually exclusive.

The number of occurrences of a particular tag in your features may be controlled by appending a colon followed by a number to the end of the tag name passed to the --tags option, like so:

cucumber --tags=@wip:3 features/log\*

The existence of more than the specified number of occurrences of that tag in all the features that are exercised during a particular Cucumber run will produce a warning message. If the --strict option is passed as well, as is the case with the default profile, then instead of a warning the run will fail.

Limiting the number of occurrences is commonly used in conjunction with the @wip tag to restrict the number of unspecified scenarios to manageable levels. Those following Kanban or Lean Software Development based methodologies will find this useful.

Running Cucumber

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby
Cucumber is a Java library with extensions for different tools and platforms. It is launched by running JUnit 4, JUnit 5, your build tool, your IDE or the CLI.
Cucumber is a Java library with extensions for different tools and platforms. It is launched by running JUnit 4, JUnit 5, your build tool, your IDE or the CLI.
Cucumber is a Java library with extensions for different tools and platforms. It is launched by running JUnit 4, JUnit 5, your build tool, your IDE or the CLI.
Cucumber is a command line tool. It is launched by running cucumber-js from the command line, or a build script.
Cucumber is a command line tool. It is launched by running cucumber from the command line, or a build script.

It is possible to configure how Cucumber should run features.

From the command line

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

The Command-Line Interface Runner (CLI Runner) is an executable Java class that can be run from the command-line.

java io.cucumber.core.cli.Main

Note that you will need to add the cucumber-core jar and all of its transitive dependencies to your classpath, in addition to the location of your compiled .class files. You can find these jars in Maven Central.

You will also need to provide the CLI with your step definitions via the --glue option followed by its package name, and the filepath of your feature file(s).

For example:

java -cp "path/to/each/jar:path/to/compiled/.class/files" io.cucumber.core.cli.Main /path/to/your/feature/files --glue hellocucumber --glue anotherpackage

Alternatively if you are using a Maven project, you can run the CLI using the Exec Maven plugin:

mvn exec:java \
-Dexec.classpathScope=test \
-Dexec.mainClass=io.cucumber.core.cli.Main \
-Dexec.args="/path/to/your/feature/files --glue hellocucumber --glue anotherpackage"

The Command-Line Interface Runner (CLI Runner) is an executable Java class that can be run from the command-line.

java io.cucumber.core.cli.Main

Note that you will need to add the cucumber-core jar and all of its transitive dependencies to your classpath, in addition to the location of your compiled .class files. You can find these jars in Maven Central.

You will also need to provide the CLI with your step definitions via the --glue option followed by its package name, and the filepath of your feature file(s).

For example:

java -cp "path/to/each/jar:path/to/compiled/.class/files" io.cucumber.core.cli.Main /path/to/your/feature/files --glue hellocucumber --glue anotherpackage

Alternatively if you are using a Maven project, you can run the CLI using the Exec Maven plugin:

mvn exec:java \
-Dexec.classpathScope=test \
-Dexec.mainClass=io.cucumber.core.cli.Main \
-Dexec.args="/path/to/your/feature/files --glue hellocucumber --glue anotherpackage"

The Command-Line Interface Runner (CLI Runner) is an executable Java class that can be run from the command-line.

java io.cucumber.core.cli.Main

Note that you will need to add the cucumber-core jar and all of its transitive dependencies to your classpath, in addition to the location of your compiled .class files. You can find these jars in Maven Central.

You will also need to provide the CLI with your step definitions via the --glue option followed by its package name, and the filepath of your feature file(s).

For example:

java -cp "path/to/each/jar:path/to/compiled/.class/files" io.cucumber.core.cli.Main /path/to/your/feature/files --glue hellocucumber --glue anotherpackage

Alternatively if you are using a Maven project, you can run the CLI using the Exec Maven plugin:

mvn exec:java \
-Dexec.classpathScope=test \
-Dexec.mainClass=io.cucumber.core.cli.Main \
-Dexec.args="/path/to/your/feature/files --glue hellocucumber --glue anotherpackage"

The most common option is to run Cucumber from the command line. By default, Cucumber will treat anything ending in.js under the root directory as a step definition file. Thus, a step contained in features/models/entities/step-definitions/anything.js can be used in a feature file, provided that:

  • Cucumber is invoked on a root directory common to both (./features, in this example); OR
  • Explicitly required on the command line

Cucumber.js includes an executable file to run the features. After installing Cucumber in a project, you can run it with:

./node_modules/.bin/cucumber.js
Global installs

Cucumber does not work when installed globally because Cucumber needs to be imported/required in support files and globally installed modules cannot be imported/required.

The most common option is to run Cucumber from the command line. By default, Cucumber will treat anything ending in .rb under the root library directory as a step definition file. Thus, a step contained in features/models/entities/step_definitions/anything.rb can be used in a feature file contained in features/views/entity_new, provided that:

  • Cucumber is invoked on a root directory common to both (./features, in this example); OR
  • Explicitly required on the command line

The following command will run the authenticate_user feature. Any feature in a subdirectory of features/ directory must require features.

cucumber --require features features/authentication/authenticate_user.feature

Note that if the --require option is passed, then ONLY that directory tree will be searched for step definition matches. You may specify the --require option multiple times if you need to include step definitions from directories that do not share a convenient root.

Otherwise, to run all features:

cucumber

You can also run features using a build tool or an IDE.

With test runners

JUnit 5 (for JVM)

See the cucumber-junit-platform-engine documentation for more information.

JUnit 4 (for JVM)

To use JUnit to execute Cucumber scenarios add the cucumber-junit dependency to your pom.

<dependencies>
[...]
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>

Note that cucumber-junit is based on JUnit 4. If you're using JUnit 5, use the cucumber-junit-platform-engine or include junit-vintage-engine dependency, as well. For more information, please refer to JUnit 5 documentation

Create an empty class that uses the Cucumber JUnit runner:

  • Java
  • Kotlin
  • Scala
packagecom.example;

importio.cucumber.junit.Cucumber;
importio.cucumber.junit.CucumberOptions;
importorg.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions()
publicclassRunCucumberTest{
}
package com.example

import io.cucumber.junit.Cucumber
import io.cucumber.junit.CucumberOptions
import org.junit.runner.RunWith

@RunWith(Cucumber::class)
@CucumberOptions()
class RunCucumberTest {
}
packagecom.example

importio.cucumber.junit.Cucumber
importio.cucumber.junit.CucumberOptions
importorg.junit.runner.RunWith

@RunWith(classOf[Cucumber])
@CucumberOptions()
class RunCucumberTest {
}

This will execute all scenarios in same package as the runner, by default glue code is also assumed to be in the same package.

The @CucumberOptions annotation can be used to provideadditional configuration to the runner.

Using plugins

For example if you want to tell Cucumber to use the two formatter plugins pretty and html, you can specify it like this:

@CucumberOptions(plugin ={"pretty","html:target/cucumber.html"})

Or if you want to tell Cucumber to print code snippets for missing step definitions use the summary plugin, you can specify it like this:

@CucumberOptions(plugin ={"pretty","summary"}, snippets =SnippetType.CAMELCASE)

The default option for snippets is UNDERSCORE. This settings can be used to specify the way code snippets will be created by Cucumber.

Performing a dry-run

For example if you want to check whether all feature file steps have corresponding step definitions, you can specify it like this:

@CucumberOptions(dryRun=true)

The default option for dryRun is false.

Formatting console output

For example if you want console output from Cucumber in a readable format, you can specify it like this:

@CucumberOptions(monochrome=true)

The default option for monochrome is false.

Select scenarios using tags

For example if you want to tell Cucumber to only run the scenarios specified with specific tags, you can specify it like this:

@CucumberOptions(tags ="@foo and not @bar")
Specify an object factory

For example if you are using Cucumber with a DI framework and want to use a custom object factory, you can specify it like this:

@CucumberOptions(objectFactory =FooFactory.class)

The default option for objectFactory is to use the default object factory. Additional information about using custom object factories can be found here

There are additional options available in the @CucumberOptions annotation.

Usually, the test class will be empty. You can, however, specify several JUnit rules.

JUnit annotations

Cucumber supports JUnits @ClassRule, @BeforeClass and @AfterClass annotations. These will be executed before and after all scenarios. Using them is not recommended, as it limits the portability between different runners; they may not execute correctly when using the command line, IntelliJ IDEA or Cucumber-Eclipse . Instead, it is recommended to use Cucumber's Before and After hooks.

The Cucumber runner acts like a suite of a JUnit tests. As such other JUnit features such as Categories, Custom JUnit Listeners and Reporters can all be expected to work.

For more information on JUnit, see the JUnit website

Options

Cucumber provides several options that can be passed via the command-line or other mechanisms.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Pass the --help option to print out all the available configuration options:

java io.cucumber.core.cli.Main --help

Cucumber will in order of precedence parse properties from system properties, environment variables and the cucumber.properties file.

Note that options provided by @CucumberOptions take precedence over the properties file and CLI arguments take precedence over all.

Note that the cucumber-junit-platform-engine is provided with properties by the Junit Platform rather than Cucumber. See junit-platform-engine Configuration Options for more information.

For example, if you are using Maven and want to run a subset of scenarios tagged with @smoke:

mvn test -Dcucumber.filter.tags="@smoke"

Supported properties are:

cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.execution.dry-run= # true or false. default: false
cucumber.execution.limit= # number of scenarios to execute (CLI only).
cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical
cucumber.execution.wip= # true or false. default: false.
cucumber.features= # comma separated paths to feature files. example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # regex. example: .*Hello.*
cucumber.filter.tags= # tag expression. example: @smoke and not @slow
cucumber.glue= # comma separated package names. example: com.example.glue
cucumber.plugin= # comma separated plugin strings. example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name. example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase. default: underscore

Note that the filter options cucumber.filter.name and cucumber.filter.tags are combined using an and operation. In other words, both expressions need to match.

Pass the --help option to print out all the available configuration options:

java io.cucumber.core.cli.Main --help

Cucumber will in order of precedence parse properties from system properties, environment variables and the cucumber.properties file.

Note that options provided by @CucumberOptions take precedence over the properties file and CLI arguments take precedence over all.

Note that the cucumber-junit-platform-engine is provided with properties by the Junit Platform rather than Cucumber. See junit-platform-engine Configuration Options for more information.

For example, if you are using Maven and want to run a subset of scenarios tagged with @smoke:

mvn test -Dcucumber.filter.tags="@smoke"

Supported properties are:

cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.execution.dry-run= # true or false. default: false
cucumber.execution.limit= # number of scenarios to execute (CLI only).
cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical
cucumber.execution.wip= # true or false. default: false.
cucumber.features= # comma separated paths to feature files. example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # regex. example: .*Hello.*
cucumber.filter.tags= # tag expression. example: @smoke and not @slow
cucumber.glue= # comma separated package names. example: com.example.glue
cucumber.plugin= # comma separated plugin strings. example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name. example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase. default: underscore

Note that the filter options cucumber.filter.name and cucumber.filter.tags are combined using an and operation. In other words, both expressions need to match.

Pass the --help option to print out all the available configuration options:

java io.cucumber.core.cli.Main --help

Cucumber will in order of precedence parse properties from system properties, environment variables and the cucumber.properties file.

Note that options provided by @CucumberOptions take precedence over the properties file and CLI arguments take precedence over all.

Note that the cucumber-junit-platform-engine is provided with properties by the Junit Platform rather than Cucumber. See junit-platform-engine Configuration Options for more information.

For example, if you are using Maven and want to run a subset of scenarios tagged with @smoke:

mvn test -Dcucumber.filter.tags="@smoke"

Supported properties are:

cucumber.ansi-colors.disabled= # true or false. default: false
cucumber.execution.dry-run= # true or false. default: false
cucumber.execution.limit= # number of scenarios to execute (CLI only).
cucumber.execution.order= # lexical, reverse, random or random:[seed] (CLI only). default: lexical
cucumber.execution.wip= # true or false. default: false.
cucumber.features= # comma separated paths to feature files. example: path/to/example.feature, path/to/other.feature
cucumber.filter.name= # regex. example: .*Hello.*
cucumber.filter.tags= # tag expression. example: @smoke and not @slow
cucumber.glue= # comma separated package names. example: com.example.glue
cucumber.plugin= # comma separated plugin strings. example: pretty, json:path/to/report.json
cucumber.object-factory= # object factory class name. example: com.example.MyObjectFactory
cucumber.snippet-type= # underscore or camelcase. default: underscore

Note that the filter options cucumber.filter.name and cucumber.filter.tags are combined using an and operation. In other words, both expressions need to match.

Use the cucumber-js --help command to see which arguments can be passed to the executable file.

For more information on how to configure options, take a look at the docs on GitHub

Assuming you've installed Cucumber as a gem, run this at a command prompt to see the options for running features:

cucumber --help

You can also define common command-line options in a cucumber.yml file.