Cucumber and JS: Getting Started with cucumber.js

January 27, 2012 in Tech

cucumberjs

The Cucumber project is a Behavior Driven Development (BDD) tool originally designed to work with Ruby. However, since its inception its popularity has grown and there have been implementations of Cucumber written for different languages including Java, .Net, Flex, and JavaScript. Cucumber understands a language named Gherkin which allows features and specs to be written in a plain text format. In this post I will step through getting started with cucumber.js - the JavaScript implementation of Cucumber, writing your first Gherkin features and making a cucumber. The instructions for this post are based on my experience on a MacBook Pro with OS X Lion 10.7.2. I don’t know exactly how these steps differ on a Windows machine. If I set up my Windows box with it I’ll update this post if there are drastically different steps. Also, feel free to post in the comments any differences and I’ll update the post.

Installing cucumber.js

In order to get cucumber.js running on your computer there are two pre-requisites that must be installed first, node.js – a JavaScript based application server, and npm – a package manager for node.js that is used to manage JavaScript libraries and their dependencies. The node.js installer now includes npm with the installation so both will be installed at the same time. Download the installer from http://nodejs.org.

Once the installer is done open a Terminal window and type ‘node -v’ and hit Enter. The node.js version number should appear, 0.6.8 at the time of this writing.

Type ‘npm list’ and hit Enter to see a list of the packages that come with the node.js default installation.

If you see lots of red text that says UNMET DEPENDENCY or INVALID the packages need to be updated so all the JavaScript libraries have everything they need to run. Type ‘npm update’ and npm will update all the packages and download any missing libraries. This could take a couple of minutes as npm downloads all of the dependencies for the packages. Once the packages are done updating and you’re back at the CLI prompt type ‘npm list’ again and you should now see a list of packages all green and no more red like below.

Now we’re ready to install the cucumber.js package. Type ‘npm install cucumber’ and npm will download the package. Once that is done go back to Terminal and type ‘cucumber.js -v’ and you should see the version number.

If you see the cucumber.js version then you are ready to start writing some Gherkin features! If you get a node.js error try checking the packages needed by cucumber.js to make sure they were all installed. Type ‘npm list’ and make sure there are no lines that say UNMET DEPENDENCY below cucumber.js. If you do see some then type ‘npm update’ again to make sure it downloads the missing packages.

Project Setup

Below is a suggested project structure for your project. Of course this is an area that is highly based on personal preference and as such this is merely a suggestion to help get you started. The things to note in the structure are the node_modules folder to start. Node.js places all of the packages that you use for a project in the node_modules folder. The Makefile is a file to use with the make command to run your cucumber.js commands. I’ll touch on that some more in the Making a Cucumber section later. The rest is arbitrary but if you change the location or names you’ll need to also update the Makefile to make sure its targets are all correct. You can use the same node_modules folder to get started from the code for this example. I got it from the Express.js sample app on the cucumber-js GitHub site. With the set up in place now you’re ready to write your first Gherkin feature and run it to see it fail.

-project folder
	-client
	-node_modules
	-tests
		-client
			-unit (jasmine, etc, another blog post...)
		-features
			-step_definitions
				-anExampleStepDef.js
			-support
				-world.js
			-AnExample.feature
	-Makefile

Writing Your First Gherkin Feature

Gherkin is the language that Cucumber implementations understand, they’re the entry point to the automated testing code you write which is referred to as the step definitions. Each step definition is in its own JavaScript file and defines the steps of a scenario of a Gherkin feature. Each feature spec is also its own file, ending in a .feature extension. Here is an example of a simple feature.

file: AnExample.feature

Feature: This is an example feature
	In order to learn Cucumber
	As a developer
	I want to make this feature pass

	Scenario: wrote my first scenario
		Given a variable set to 1
		When I increment the variable by 2
		Then the variable should contain 3

There are several parts to the feature definition. All features start with the keyword “Feature:”, followed by a short description or feature name. The lines that follow immediately below are indented by a single tab and always go in the pattern: “In order to…”, “As a …”, “I want to…”. This pattern comes from some of the basic tenets of BDD, which there is a good description of on Wikipedia (http://en.wikipedia.org/wiki/Behavior_Driven_Development). Immediately following the description of the feature are N number of Scenario definitions. In the example above there is only one but multiple scenarios can be expressed for a single feature. Scenarios always start with the keyword “Scenario:”, followed by a short description of what that scenario for that particular feature is about to be described in the following steps. The steps that follow are the most vital part of the feature definition as they directly tie in to the cucumber step definitions you’ll be writing to verify this feature. We will see how exactly those tie together in the next section Writing Your First Step Definition. These steps always start with the keywords “Given”, “When”, and “Then”. Additionally you can use the keyword “And” after any of the keywords. You can read a lot more about Gherkin and its syntax and examples by checking out the book Specification by Example (http://manning.com/adzic/). This example is a very basic one just to show how it all works and comes together. With this feature file in place we can now write the step definition to start testing this feature with cucumber.js.

Writing Your First Step Definition

The step definition code should go in its own JavaScript file per feature. In the code example below the JavaScript file is named after the feature file name with a js extension.

file: anExampleStepDef.js

var aTest = function () {
	this.World = require("../support/world.js").World;

	this.givenNumber = 0;

	this.Given(/^a variable set to (\d+)$/, function(number, next) {
		this.givenNumber = parseInt(number);
		next();
	});

	this.When(/^I increment the variable by (\d+)$/, function (number, next) {
		this.givenNumber = this.givenNumber + parseInt(number);
		next();
	});

	this.Then(/^the variable should contain (\d+)$/, function (number, next) {
		if (this.givenNumber != number)
			throw(new Error("This test didn't pass, givenNumber is " + this.givenNumber + " expected 0"));
		next();
	});
};

module.exports = aTest;

Lets break down this step definition. The function assigned to the aTest variable is the code that will verify the Gherkin feature. The first line of the function is the set up for the step definition, similar to the set up of a FlexUnit or any other xUnit test case. A World variable is defined that accepts a callback that is passed in by cucumber.js. In the World function is where you would set up beforeEach(), afterEach() and all the set up that needs to happen for this “world”. The last line tells cucumber.js its ready to go and passes in the reference to “this”.

file: world.js

var World = function (callback) {
	// set up code goes here

	// last line to tell cucumber.js the World is ready.
	callback(this);
};

exports.World = World;

The next three function calls are where the step definition directly ties in to the feature file. Each of the steps of the scenario that the step definition js file is testing is written with the function calls to ‘this.Given()’, ‘this.When()’ and ‘this.Then()’. The first argument of each function is a regular expression that will match the plain english in its matching step in the feature file. The phrase “Given a variable set to 1″ then translates to “this.Given(/^a variable set to (\d+)$/, function (number, next) {…})”. The callback function that is in the second argument will always have at least a single argument sent in which is the callback function to call at the end of the step, in this example named ‘next’. If there are regular expression tokens, such as ‘(\d+)’ to catch a digit those are sent in to the callback function and can be named arbitrarily and sent to the function call in the order that they appear. That is why the function call has two arguments: ‘function (number, next) {…}’.

With these files in place now we can move on to making a cucumber. But first we’ll have to talk about the Makefile.

The Makefile

Because cucumber.js is a command line interface program it is cumbersome to use frequently when the parameters list is long or they have to change often. The make utility solves the problem and a Makefile are the instructions to make the process of running and making a cucumber more efficient by having predetermined build targets. Below is an example of a basic Makefile to run cucumber.js on the feature in this example.

file: Makefile

cucumber:
		@NODE_ENV=test ./node_modules/.bin/cucumber.js tests/features \
				-r tests/features/step_definitions

.PHONY: cucumber

You can also add additional targets so you can for example run node.js server tests with mocha or run your client unit tests written in Jasmine from the same Makefile. I will expand on those in a later post or you can also check out the Express.js application example mentioned in the cucumber-js GitHub repo README file. The paths in the Makefile file are relative to the location of the Makefile which is the same directory you run the make command from.

Finally, Making a Cucumber

With the Makefile in place we can finally make a cucumber. From the directory with the Makefile, which is usually the project root, open a Terminal. Type ‘make cucumber’ and you should see some output from cucumber.js telling you how many features were tested and how many scenarios were tested, including how many passed and failed.

If you scroll up the output will give you the details about the step that failed.

That’s it! If your code has a bug or error in it it’ll look like above. If it is passing cucumber.js will look like the screenshot below. There’s a bit of set up upfront, but I believe its worth the price of admission and once its set up all you have to type again is “make cucumber” to test your code… and its fast! If you want more information about Cucumber I would recommend the new e-book/paperback that’s available in beta form due out in February 2012 and the Specification by Example book which are both on the http://cukes.info page.

Happy cuking!