Cucumber.js
Cucumber, the popular Behaviour-Driven Development tool, brought to your JavaScript stack.
It runs on both Node.js and modern web browsers.
Try it now: http://cucumber.no.de!
Development status
Cucumber.js is still a work in progress. Here is its current status.
Cucumber Technology Compatibility Kit
- Not certified by Cucumber TCK yet.
- Considered for removal from Cucumber TCK.
- Missing 'matches' attributes. Simple wrapper for Gherkin's
JsonFormatter
pending porting of:
in Gherkin itself.
Cucumber.js-specific features
- Will be certified by Cucumber TCK.
Prerequesites
Cucumber.js is tested on:
- Node.js 0.6 or 0.7 (see CI builds)
- Google Chrome
- Firefox
- Safari
- Opera
There are plans to have CI builds on browsers too.
Usage
Install
Cucumber.js is available as an npm module.
Install globally with:
$ npm install -g cucumber
OR
You may also define cucumber.js as a development dependency of your application by including it in a package.json file.
{ "devDependencies" : {
"cucumber": "latest"
}
}
Then install with npm install --dev
Features
Features are written with the Gherkin syntax
# features/myFeature.feature
Feature: Example feature
As a user of cucumber.js
I want to have documentation on cucumber
So that I can concentrate on building awesome applications
Scenario: Reading documentation
Given I am on the Cucumber.js Github repository
When I go to the README file
Then 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. Both JavaScript (.js
) and CoffeeScript (.coffee
) source files are supported.
World
World is a constructor function with utility properties, destined to be used in step definitions:
var zombie = require('zombie');
var World = function World(callback) {
this.browser = new zombie.Browser();
this.visit = function(url, callback) {
this.browser.visit(url, callback);
};
callback();
};
exports.World = World;
It is possible to tell Cucumber to use another object instance than the constructor:
var zombie = require('zombie');
var WorldConstructor = function WorldConstructor(callback) {
this.browser = new zombie.Browser();
var world = {
visit: function(url, callback) {
this.browser.visit(url, callback);
}
};
callback(world);
};
exports.World = WorldConstructor;
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
.
var myStepDefinitionsWrapper = function () {
this.World = require("../support/world.js").World;
this.Given(/^I am on the Cucumber.js Github repository$/, function(callback) {
this.visit('http://github.com/cucumber/cucumber-js', callback);
});
this.When(/^I go to the README file$/, function(callback) {
callback.pending();
});
this.Then(/^I should see "(.*)" as the page title$/, function(title, callback) {
if (!this.isOnPageWithTitle(title))
callback.fail(new Error("Expected to be on page with title " + title));
else
callback();
});
};
module.exports = myStepDefinitionsWrapper;
It is also possible to use simple strings instead of regexps as step definition patterns:
this.Then('I should see "$title" as the page title', function(title, callback) {
if (!this.isOnPageWithTitle(title))
callback.fail(new Error("Expected to be on page with title " + title));
else
callback();
});
'I have $count "$string"'
would translate to /^I have (.*) "([^"]*)")$/
.
Hooks
Hooks can be used to prepare and clean the environment before and after each scenario is executed.
Before hooks
To run something before every scenario, use before hooks:
var myHooks = function () {
this.Before(function(callback) {
this.bootFullTextSearchServer();
this.createSomeUsers();
callback();
});
};
module.exports = myHooks;
After hooks
The before hook counterpart is the after hook. It's similar in shape but is executed, well, after every scenario:
var myAfterHooks = function () {
this.After(function(callback) {
this.emptyDatabase();
this.shutdownFullTextSearchServer();
callback();
});
};
module.exports = myAfterHooks;
Around hooks
It's also possible to combine both before and around hooks in one single definition with the help of around hooks:
myAroundHooks = function() {
this.Around(function(runScenario) {
this.bootFullTextSearchServer();
this.createSomeUsers();
runScenario(function(callback) {
this.emptyDatabase();
this.shutdownFullTextSearchServer();
callback();
});
});
};
module.exports = myAroundHooks;
Tagged hooks
Hooks can be conditionally elected for execution based on the tags of the scenario.
var myHooks = function () {
this.Before("@foo", "@bar,@baz", function(callback) {
callback();
});
};
module.exports = myHooks;
Run cucumber
Cucumber.js includes a binary file to execute the features.
If you installed cucumber.js globally, you may run it with:
$ cucumber.js
You may specify the features to run:
$ cucumber.js features/my_feature.feature
And require specific step definitions and support code files with the --require option:
$ cucumber.js features/my_feature.feature --require features/step_definitions/my_step_definitions.js
If you installed Cucumber locally or with npm install --dev
, you'll 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.
Examples
A few example apps are available for you to browse:
Contribute
See CONTRIBUTE.
Help & support