VOOZH about

URL: https://cucumber.io/docs/cucumber/configuration/

⇱ Configuration | Cucumber


Skip to main content

Parameter types

Parameter types let you convert parameters from Cucumber expressions to objects.

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Data table and doc string types let you convert data tables and doc strings to objects. Like step definitions, type definitions are part of the glue. When placed on the glue path Cucumber will detect them automatically.

For example, the following class registers a custom "Author" data table type:

packagecom.example;

importio.cucumber.java.DataTableType;
importio.cucumber.java.en.Given;

importjava.util.List;
importjava.util.Map;

publicclassStepDefinitions{

@DataTableType
publicAuthorauthorEntry(Map<String,String> entry){
returnnewAuthor(
entry.get("firstName"),
entry.get("lastName"),
entry.get("famousBook"));
}

@Given("These are my favorite authors")
publicvoidthese_are_my_favourite_authors(List<Author> authors){
// step implementation
}
}

This class registers a custom "Book" type from an expression:

packagecom.example;

importio.cucumber.java.ParameterType;
importio.cucumber.java.en.Given;

publicclassStepDefinitions{

@ParameterType(".*")
publicBookbook(String bookName){
returnnewBook(bookName);
}

@Given("{book} is my favorite book")
publicvoidthis_is_my_favorite_book(Book book){
// step implementation
}
}

This class registers a custom type for a doc string:

packagecom.example;

importcom.fasterxml.jackson.core.JsonProcessingException;
importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper;
importio.cucumber.java.DocStringType;
importio.cucumber.java.en.Given;

publicclassStepsDefinitions{

privatestaticObjectMapper objectMapper =newObjectMapper();

@DocStringType
publicJsonNodejson(String docString)throwsJsonProcessingException{
return objectMapper.readValue(docString,JsonNode.class);
}

@Given("Books are defined by json")
publicvoidbooks_are_defined_by_json(JsonNode books){
// step implementation
}
}

For lambda-defined step definitions, there are DataTableType, ParameterType and DocStringType functions:

packagecom.example;

importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper;

importio.cucumber.java8.En;

importjava.util.Map;

publicclassLambdaStepDefinitionsimplementsEn{

privatestaticObjectMapper objectMapper =newObjectMapper();

publicLambdaStepDefinitions(){

DataTableType((Map<String,String> entry)->newAuthor(
entry.get("firstName"),
entry.get("lastName"),
entry.get("famousBook")
));

ParameterType("book",".*",(String bookName)->newBook(bookName));

DocStringType("json",(String docString)->
objectMapper.readValue(docString,JsonNode.class));
}
}

Using the @DefaultParameterTransformer, @DefaultDataTableEntryTransformer and @DefaultDataTableCellTransformer annotations, it is also possible to plug in an object mapper. The object mapper (Jackson in this example) will handle the conversion of anonymous parameter types and data table entries:

packagecom.example;

importcom.fasterxml.jackson.databind.ObjectMapper;
importio.cucumber.java.DefaultDataTableCellTransformer;
importio.cucumber.java.DefaultDataTableEntryTransformer;
importio.cucumber.java.DefaultParameterTransformer;

importjava.lang.reflect.Type;

publicclassStepDefinitions{

privatefinalObjectMapper objectMapper =newObjectMapper();

@DefaultParameterTransformer
@DefaultDataTableEntryTransformer
@DefaultDataTableCellTransformer
publicObjecttransformer(Object fromValue,Type toValueType){
return objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType));
}
}

For lambda-defined step definitions, there are DefaultParameterTransformer, DefaultDataTableCellTransformer and DefaultDataTableEntryTransformer methods:

packagecom.example;

importio.cucumber.java8.En;

importcom.fasterxml.jackson.databind.ObjectMapper;

importjava.lang.reflect.Type;

publicclassLambdaStepDefinitionsimplementsEn{

publicLambdaStepDefinitions(){
ObjectMapper objectMapper =newObjectMapper();

DefaultParameterTransformer((String fromValue,Type toValueType)->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType)));

DefaultDataTableCellTransformer((fromValue, toValueType)->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType)));

DefaultDataTableEntryTransformer((fromValue, toValueType)->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType)));
}
}

Data table and doc string types let you convert data tables and doc strings to objects. Like step definitions, type definitions are part of the glue. When placed on the glue path Cucumber will detect them automatically.

For example, the following class registers a custom "Author" data table type:

package com.example

import io.cucumber.java.DataTableType
import io.cucumber.java.en.Given
import kotlin.streams.toList

class StepDefinitions {

@DataTableType
funauthorEntry(entry: Map<String, String>): Author {
returnAuthor(
entry["firstName"],
entry["lastName"],
entry["famousBook"])
}

@Given("There are my favorite authors")
funthese_are_my_favourite_authors(authors: List<Author>){
// step implementation
}
}

This class registers a custom "Book" type from an expression:

package com.example

import io.cucumber.java.ParameterType
import io.cucumber.java.en.Given

class StepDefinitions {

@ParameterType(".*")
funbook(bookName: String): Book {
returnBook(bookName)
}

@Given("{book} is my favorite book")
funthis_is_my_favorite_book(book: Book){
// step implementation
}
}

This class registers a custom type for a doc string:

package com.example

import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import io.cucumber.java.DocStringType
import io.cucumber.java.en.Given

class StepsDefinitions {

companionobject{
privateval objectMapper =ObjectMapper()
}

@DocStringType
@Throws(JsonProcessingException::class)
funjson(docString: String): JsonNode {
return objectMapper.readValue(docString, JsonNode::class)
}

@Given("Books are defined by json")
funbooks_are_defined_by_json(books: JsonNode){
// step implementation
}
}

For lambda-defined step definitions, there are DataTableType, ParameterType and DocStringType functions:

package com.example

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper

import io.cucumber.java8.En

class LambdaStepDefinitions : En {

init{
val objectMapper =ObjectMapper()

ParameterType("book",".*"){ s : String ->
Book(s)
}

DataTableType { entry: Map<String, String>->
Author(entry["firstName"], entry["lastName"], entry["famousBook"])
}

DocStringType("json"){ docString: String ->
objectMapper.readValue(docString, JsonNode::class)
}
}
}

Using the @DefaultParameterTransformer, @DefaultDataTableEntryTransformer and @DefaultDataTableCellTransformer annotations, it is also possible to plug in an object mapper. The object mapper (Jackson in this example) will handle the conversion of anonymous parameter types and data table entries:

package com.example

import com.fasterxml.jackson.databind.ObjectMapper
import io.cucumber.java.DefaultDataTableCellTransformer
import io.cucumber.java.DefaultDataTableEntryTransformer
import io.cucumber.java.DefaultParameterTransformer

import java.lang.reflect.Type

class StepDefinitions {

privateval objectMapper =ObjectMapper()

@DefaultParameterTransformer
@DefaultDataTableEntryTransformer
@DefaultDataTableCellTransformer
funtransformer(fromValue: Any, toValueType: Type): Any {
return objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}
}

For lambda-defined step definitions, there are DefaultParameterTransformer, DefaultDataTableCellTransformer and DefaultDataTableEntryTransformer methods:

import com.fasterxml.jackson.databind.ObjectMapper

import io.cucumber.java8.En
import java.lang.reflect.Type

class LambdaStepDefinitions : En {
init{
val objectMapper =ObjectMapper()

DefaultParameterTransformer { fromValue: String, toValueType: Type ->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}

DefaultDataTableCellTransformer { fromValue, toValueType ->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}

DefaultDataTableEntryTransformer { fromValue, toValueType ->
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}
}
}

Data table and doc string types let you convert data tables and doc strings to objects. Like step definitions, type definitions are part of the glue. When placed on the glue path Cucumber will detect them automatically.

For example, the following class registers a custom "Author" data table type:

packagecom.example

importio.cucumber.scala.{ScalaDsl, EN}

class StepDefinitions extends ScalaDsl with EN {

DataTableType { entry: Map[String,String]=>
Author(
entry("firstName"),
entry("lastName"),
entry("famousBook"))
}

Given("There are my favorite authors"){ authors: List[Author]=>
// step implementation
}
}

This class registers a custom "Book" type from an expression:

packagecom.example

importio.cucumber.scala.{ScalaDsl, EN}

class StepDefinitions extends ScalaDsl with EN {

ParameterType("book",".*"){ bookName:String=>
Book(bookName)
}

Given("{book} is my favorite book"){ book: Book =>
// step implementation
}
}

This class registers a custom type for a doc string:

packagecom.example

importcom.fasterxml.jackson.core.JsonProcessingException
importcom.fasterxml.jackson.databind.JsonNode;
importcom.fasterxml.jackson.databind.ObjectMapper
importio.cucumber.scala.{ScalaDsl, EN}

object StepsDefinitions {
privateval objectMapper = ObjectMapper()
}

class StepsDefinitions extends ScalaDsl with EN {

DocStringType("json"){ docString:String=>
objectMapper.readValue(docString, classOf[JsonNode])
}

Given("Books are defined by json"){ books: JsonNode =>
// step implementation
}
}

Using the DefaultParameterTransformer, DefaultDataTableEntryTransformer and DefaultDataTableCellTransformer methods, it is also possible to plug in an object mapper. The object mapper (Jackson in this example) will handle the conversion of anonymous parameter types and data table entries:

packagecom.example

importcom.fasterxml.jackson.databind.ObjectMapper
importio.cucumber.scala.ScalaDsl

importjava.lang.reflect.Type

class StepDefinitions extends ScalaDsl {

privateval objectMapper = ObjectMapper()

DefaultParameterTransformer {(fromValue:String, toValueType: Type)=>
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}

DefaultDataTableCellTransformer {(fromValue:String, toValueType: Type)=>
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}

DefaultDataTableEntryTransformer {(fromValue: Map[String,String], toValueType: Type)=>
objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType))
}
}

If you want to, you can use the predefined JacksonDefaultDataTableEntryTransformer trait which defines default transformers using Jackson Scala Module.

See Default Jackon DataTable Transformer.

See the cucumber-js docs on GitHub for more on working with parameter types and data tables in JavaScript.

A parameter type lets you transform an argument from a string to another type before it's passed to the step definition.

For example, let's define our own "Person" type:

ParameterType(
name:'person',
regexp:/[A-Z][a-z]+/,
transformer:->(name){Person.new(name)}
)

Here's an example of how to use this in a step definition:

Then('a user {person} should have {int} followers')do|person, count|
puts person.is_a?(Person)
end

If you try to use a type that has not yet been defined, you will see an error similar to:

The parameter type "person" is not defined.

Profiles

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby

Cucumber profiles are not available on Cucumber-JVM. However, it is possible to set configuration options using Maven profiles

For instance, we can configure separate profiles for scenarios which are to be run in separate environments like so:

<profiles>
<profile>
<id>dev</id>
<properties>
<cucumber.filter.tags>@dev and not @ignore</cucumber.filter.tags>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<cucumber.filter.tags>@qa</cucumber.filter.tags>
</properties>
</profile>
</profiles>

<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<systemPropertyVariables>
<cucumber.filter.tags>${cucumber.filter.tags}</cucumber.filter.tags>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>

To mimick similar behavior using Gradle, see the Gradle docs on Migrating Maven profiles and properties.

Cucumber profiles are not available on Cucumber-JVM. However, it is possible to set configuration options using Maven profiles

For instance, we can configure separate profiles for scenarios which are to be run in separate environments like so:

<profiles>
<profile>
<id>dev</id>
<properties>
<cucumber.filter.tags>@dev and not @ignore</cucumber.filter.tags>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<cucumber.filter.tags>@qa</cucumber.filter.tags>
</properties>
</profile>
</profiles>

<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<systemPropertyVariables>
<cucumber.filter.tags>${cucumber.filter.tags}</cucumber.filter.tags>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>

To mimick similar behavior using Gradle, see the Gradle docs on Migrating Maven profiles and properties.

Cucumber profiles are not available on Cucumber-JVM. However, it is possible to set configuration options using Maven profiles

For instance, we can configure separate profiles for scenarios which are to be run in separate environments like so:

<profiles>
<profile>
<id>dev</id>
<properties>
<cucumber.filter.tags>@dev and not @ignore</cucumber.filter.tags>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<cucumber.filter.tags>@qa</cucumber.filter.tags>
</properties>
</profile>
</profiles>

<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<systemPropertyVariables>
<cucumber.filter.tags>${cucumber.filter.tags}</cucumber.filter.tags>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>

To mimick similar behavior using Gradle, see the Gradle docs on Migrating Maven profiles and properties.

See the cucumber-js docs on GitHub for more on how to work with profiles in JavaScript.

You can specify configuration options for Cucumber in a cucumber.yml or cucumber.yaml file. This file must be in a .config directory, or config subdirectory of your current working directory.

config/cucumber.yml
## ##YAML Template
html_report:--format progress --format html --out=features_report.html
bvt:--tags @bvt

Defining a template requires a name and then the command-line options that you want to execute with this profile.

The example above generates two profiles:

  1. html_report, with a list of command-line options that specify new output formats, and
  2. bvt, which executes all Features and Scenarios tagged with @bvt.

Cucumber-Rails creates a cucumber.yml file in the project config directory containing a number of predefined profiles, one of which is the default profile. When Cucumber is run from the command line, it is usually necessary to provide both the directory name containing the root directory of the tree containing feature files and the directory name containing references to the necessary library files. In a typical project, cucumber --require features features/some/path will suffice. Repetitious usages can be added to user-defined profiles contained in the project's cucumber.yml file.

To execute the profile, use:

\[user@system project] cucumber --profile html_report
\[user@system project] cucumber -p bvt

Use the flag --profile or -p to execute Cucumber with a profile. You can still use other command line arguments alongside --profile or -p, if desired.

\[user@system project] cucumber --profile html_report --tags ~@wip

Multiple profiles can even be specified together. The following executes all Features and Scenarios tagged @bvt, with the specified progress and HTML output.

\[user@system project] cucumber -p html_report -p bvt

Chances are you’ll want to execute Cucumber with a particular profile most of the time. The Cucumber configuration file uses a default profile to provide this functionality. When you specify a default profile, you are telling Cucumber to use the default command-line options whenever you don't explicitly specify a different profile.

Using the same example, perhaps we want the html_report profile to be our default execution.

1. config/cucumber.yml
## ##YAML Template
default:--profile html_report --profile bvt
html_report:--format progress --format html --out=features_report.html
bvt:--tags @bvt
\[user@system project] cucumber

With this setup, Cucumber will now use both the bvt profile and html_report profile, testing all Features and Scenarios tagged with @bvt, along with the progress output and HTML output.

The cucumber.yml file is preprocessed by ERB (Embedded RuBy). This allows you to use Ruby code to generate values in the cucumber.yml file.

So, if you have several profiles with similar values, you might do this:

1. config/cucumber.yml
## ##YAML Template
<% common = "--tags ~@wip --strict" %>
default: <%= common %> features
html_report: <%= common %>--format html --out=features_report.html features

Environment variables

  • Java
  • Kotlin
  • Scala
  • JavaScript
  • Ruby
Cucumber-JVM does not support configuration with an env file.
Cucumber-JVM does not support configuration with an env file.
Cucumber-JVM does not support configuration with an env file.
Cucumber-JS does not support configuration with an env file.

You can use environment variables in the profile argument list, just as you would normally specify them on the command-line.

1. config/cucumber.yml
\##YAML Template
2. ## ie profile executes the browser features with Internet Explorer
default:--profile html_report --profile bvt
html_report:--format progress --format html --out=features_report.html
bvt:--tags @bvt
ie: BROWSER=IE

When running Cucumber, it can sometimes be handy to pass special values to Cucumber for your step definitions to use.

You can do this on the command line:

cucumber FOO=BAR --format progress features

You can now pick up ENV\['FOO'] in Ruby (for example, in env.rb, or a Step Definition) and perform actions according to the value.

You can also do this in cucumber.yml.

For example, the following sets up a profile that runs the specified Tag and sets an environment variable:

baz:--tags @mytag FOO=BAR

Local Cucumber customisation code in support/env.rb itself as that file is typically overwritten by script/generate cucumber:install | rails g cucumber. Customisations that must be loaded before the rest of Cucumber initialises must be placed at the beginning of the env.rb file.

Every file ending in .rb that is found in features/support is loaded by Cucumber. Therefore, if you place local customisations in any .rb file in that directory, they will get loaded. However, be advised that in Cucumber < 4.x, the --dry-run option only excludes files in features/support that match the regexp /env\\..\*/ (note that the trailing dot is significant). So a file with local customisations called my_locals.rb will be loaded regardless. In Cucumber 4.x, all support files, including env.rb files, are loaded.

If you put custom files inside features/support that you do not wish loaded when you do a dry-run with Cucumber, you can use the --exclude flag to ensure they aren't loaded. In Cucumber versions < 4.x, you can also prefix the filenames with env, as in env.local.rb. Note that a file called local_env.rb, for example, does not match the regex above and therefore will be loaded in all versions of Cucumber unless specifically excluded.

As a matter of good practice you should always run script/generate cucumber | rails g cucumber:install whenever you install an updated version of Cucumber or cucumber-rails. However, this overwrites features/support/env.rb. In order to keep any custom configurations from your env.rb file, check in your env.rb along with the rest of your version controlled files and be prepared to diff and merge changes to env.rb between versions of Cucumber-Rails.