Cucumber.js
Important This is not the main Cucumberjs project. That is at https://www.npmjs.com/package/cucumber
Cucumber, the popular Behaviour-Driven Development tool, brought to your JavaScript stack.
It runs on both Node.js and modern web browsers.
Prerequesites
Cucumber.js is tested on:
- Node.js 4.x, 0.12, 0.10, and io.js (see CI builds)
- Google Chrome
- Firefox
- Safari
- Opera
Usage
Install
Cucumber.js is available as an npm module.
Install globally with:
$ npm install -g cucumber
Install as a development dependency of your application with:
$ npm install --save-dev cucumber
Features
Features are written with the Gherkin syntax
# features/myFeature.featureFeature: Example featureAs a user of cucumber.jsI want to have documentation on cucumberSo that I can concentrate on building awesome applicationsScenario: Reading documentationGiven I am on the Cucumber.js GitHub repositoryWhen I go to the README fileThen I should see "Usage" as the page title
Support Files
Support files let you setup the environment in which steps will be run, and define step definitions.
World
World is a constructor function with utility properties, destined to be used in step definitions:
// features/support/world.jsvar zombie = ; { thisbrowser = ; // this.browser will be available in step definitions this { thisbrowser; };} // Should you need asynchronous operations when World is intantiated (i.e. before every scenario), use a hook with a callback or returning a promise (see Hooks below for more information): { var server = ; server;} module { thisWorld = World; thisBefore = Before;};
Step Definitions
Step definitions are the glue between features written in Gherkin and the actual SUT (system under test). They are written in JavaScript.
All step definitions will run with this
set to what is known as the World in Cucumber. It's an object exposing useful methods, helpers and variables to your step definitions. A new instance of World
is created before each scenario.
Step definitions are contained within one or more wrapper functions.
Those wrappers are run before executing the feature suite. this
is an object holding important properties like the Given()
, When()
and Then()
functions. Another notable property is World
; it contains a default World
constructor that can be either extended or replaced.
Step definitions are run when steps match their name. this
is an instance of World
.
// features/step_definitions/myStepDefinitions.jsmodule {this;this;this;};
Promises
Instead of Node.js-style callbacks, promises can be returned by step definitions:
this;
Simply omit the last callback
parameter and return the promise.
Synchronous step definitions
Often, asynchronous behaviour is not needed in step definitions. Simply omit the callback parameter, do not return anything and Cucumber will treat the step definition function as synchronous:
this;
Strings instead of regular expressions
It is also possible to use simple strings instead of regexps as step definition patterns:
this;
'I have $count "$string"'
would translate to /^I have (.*) "([^"]*)"$/
.
Data Table
When steps have a data table, they are passed an object with methods that can be used to access the data.
- with column headers
hashes
: returns an array of objects where each row is converted to an object (column header is the key)rows
: returns the table as a 2-D array, without the first row
- without column headers
raw
: returns the table as a 2-D arrayrowsHash
: returns an object where each row corresponds to an entry (first column is the key, second column is the value)
See this feature for examples
Timeouts
By default, asynchronous hooks and steps timeout after 5000 milliseconds. This can be modified globally with:
// features/support/env.js var { this;}; moduleexports = configure;
A specific step's timeout can be set with:
// features/step_definitions/my_steps.js var { this;}; moduleexports = mySteps;
Hooks
Hooks can be used to prepare and clean the environment before and after each scenario is executed. Hooks can use callbacks, return promises, or be synchronous. The first argument to hooks is always the current scenario. See Cucumber.Api.Scenario for more information.
Before hooks
To run something before every scenario, use before hooks:
// features/support/hooks.js (this path is just a suggestion)var {this;};moduleexports = myHooks;
If you need to run asynchronous code, simply accept a callback in your hook function and run it when you're done:
this;
Or return a promise:
this;
After hooks
The before hook counterpart is the after hook. It's similar in shape but is executed, well, after every scenario:
// features/support/after_hooks.js var { this;}; moduleexports = myAfterHooks;
Around hooks
It's also possible to combine both before and after hooks in one single definition with the help of around hooks:
// features/support/advanced_hooks.js { this;}; moduleexports = myAroundHooks;
As with Before
and After
hooks, Around
hooks functions (both pre- and post-scenario functions) can accept a callback or return a promise if you need asynchronous operations.
Tagged hooks
Hooks can be conditionally elected for execution based on the tags of the scenario.
// features/support/hooks.js (this path is just a suggestion)var {this;};moduleexports = myHooks;
Attachments
You can attach text, images and files to the Cucumber report using the scenario object:
this;
By default, text is saved with a MIME type of text/plain
. You can also specify
a different MIME type:
this;
Images and other binary data can be attached using a stream.Readable. In that case, passing a callback to attach()
becomes mandatory:
this;
Images and binary data can also be attached using a Buffer:
this;
Here is an example of saving a screenshot using WebDriver when a scenario fails:
this;
After features event
The after features event is emitted once all features have been executed, just before the process exits. It can be used for tasks such as closing your browser after running automated browser tests with selenium or phantomjs.
note: There are "Before" and "After" events for each of the following: "Features", "Feature", "Scenario", "Step" as well as the standalone events "Background" and "StepResult". e.g. "BeforeScenario".
// features/support/after_hooks.jsvar { this;} moduleexports = myAfterHooks;
CLI
Cucumber.js includes a binary file to execute the features.
If you installed cucumber.js globally, you may run it with:
$ cucumber.js
If you installed Cucumber locally, you may need to specify the path to the binary:
$ ./node_modules/.bin/cucumber.js
Note to Windows users: invoke Cucumber.js with cucumber-js
instead of cucumber.js
. The latter is causing the operating system to invoke JScript instead of Node.js, because of the so-called file extension.
Running specific features
- Specify a feature file
$ cucumber.js features/my_feature.feature
- Specify a scenario by its line number
$ cucumber.js features/my_feature.feature:3
- Use Tags
Requiring support files
Use --require <FILE|DIR>
to require files before executing the features.
If not used, all "*.js" files (and other extensions specifed by --compiler
) that are siblings
or below the features will be loaded automatically. Automatic
loading is disabled when this option is specified, and all loading becomes explicit.
Files under directories named "support" are always loaded first
Formatters
Use --format <TYPE[:PATH]>
to specify the format of the output.
If PATH is not supplied, the formatter prints to stdout.
If PATH is supplied, it prints to the given file.
If multiple formats are specified with the same output, only the last is used.
Built-in formatters
- pretty - prints the feature as is (default)
- progress - prints one character per scenario
- json - prints the feature as JSON
- summary - prints a summary only, after all scenarios were executed
Tags
Use --tags <EXPRESSION>
to run specific features or scenarios.
--tag @dev
: tagged with @dev--tag ~@dev
: NOT tagged with@dev
--tags @foo,@bar
: tagged with@foo
ORbar
--tags @foo --tags @bar
: tagged with@foo
ANDbar
Transpilers
Step definitions and support files can be written in other languages that transpile to javascript.
This done with the CLI option --compiler <file_extension>:<module_name>
.
Below are some examples
- CoffeeScript:
--compiler coffee:coffee-script/register
- TypeScript:
--compiler ts:ts-node/register
- Pogo:
--compiler pogo:pogo
Custom Snippet Syntax
Undefined steps snippets are printed in javascript by default.
Custom snippet snytaxes can be used with --snippet-syntax <FILE>
.
See here for an example.
Building a custom snippet syntax
- See the JavaScript syntax for an example. Please open an issue if you need more information.
- Please add the keywords
cucumber
andsnippets
to your package, so it can easily be found by searching npm.
Examples
A few example apps are available for you to browse:
Contribute
See CONTRIBUTING.
Help & support
- Twitter: @cucumber_js
- IRC: #cucumber on Freenode
- Google Groups: cukes
- Website: cucumber.io