Skip to content

Commit

Permalink
Add usage documentation to README (close #23)
Browse files Browse the repository at this point in the history
- Improve the usage documentation within the README
- Link to example application
  • Loading branch information
olivoil authored and jbpros committed Dec 7, 2011
1 parent 4f5f301 commit 1e29b6a
Showing 1 changed file with 113 additions and 2 deletions.
115 changes: 113 additions & 2 deletions README.md
Expand Up @@ -70,9 +70,120 @@ Cucumber.js was tested on:
* Firefox
* Safari

## Use it
## Usage

#### Install

Cucumber.js is available as an npm module.

Install globally with:

``` shell
$ 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.

``` json
// package.json

{ "devDependencies" : {
"cucumber": "latest"
}
}
```

Then install with `npm install --dev`


#### Features

Features are written with the [Gherkin syntax](https://github.com/cucumber/cucumber/wiki/Gherkin)

``` gherkin
// 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 page
When I go to the README file
Then I should see "Usage"
```

#### Support Files

Support files let you setup the environment in which steps will be run, and define step definitions.

##### World

A World is a constructor function with utility properties, destined to be used in step definitions

``` javascript
// features/support/world.js

require('zombie');
var World = module.exports = function(){
this.browser = new zombie.Browser(); // this.browser will be available in step definitions

this.visit = function(url){
this.browser.visit(url, callback(err, browser, status){
callback(err, browser, status);
});
};
};
```

##### Step Definitions

Step definitions are written in javascript.
Each step definition has a World property that can be set to a constructor function.
Each individual step will be executed in the context of an instance of the World function.
(i.e. `this` inside a step will refer to a newly created instance of the World property, making sure state stays consistent between each step.)


``` javascript
// features/step_definitions/myStepDefinitions.js

var myStepDefinitions = function(){
this.World = require(" <path to the world file> ");

this.Given( <REGEXP>, function(next){
// express the regexp above with the code you wish you had
// this is set to a new this.World instance
// i.e. you may use this.browser to execute the step...

this.browser.visit('http://github.com/cucumber/cucumber-js', next);
});

this.When( <REGEXP>, function(next) {
// express the regexp above with the code you wish you had
// Call next() at the end of the step, or next.pending() if the step is not yet implemented.
next.pending();

This comment has been minimized.

Copy link
@jbpros

jbpros Dec 9, 2011

Member

I'm not sure I like giving the name next to the callback. It looks great when you call it normally, but in cases like this one (i.e. when you call its pending function) then it feels a bit odd. It seems to command the next step to be pending instead of the current one.

@olivoil What do you think?

This comment has been minimized.

Copy link
@olivoil

olivoil Dec 9, 2011

Author Contributor

I agree that next.pending() miss communicates the intention here.
Mocha uses done for it's async tests callback. Maybe that would be better? done.pending() sounds clearer, and done() is more communicative than a plain callback().

Although, I feel it would be more intuitive to call this.pending() to throw a pending step exception. How would you feel about that?

This comment has been minimized.

Copy link
@olivoil

olivoil Dec 9, 2011

Author Contributor

Maybe that could be done by extending a default world implementation instead of just overwriting it? So that it exposes a pending function, that would then throw a pending step exception. StepDefinition could expose a convenience method, like this.extendWorld( require('myWorld').World ) that users would call instead of doing this.World = require('myWorld').World. We would then extend our default World constructor with the one provided by the user...

@jbpros Does it make sense?

This comment has been minimized.

Copy link
@jbpros

jbpros Dec 9, 2011

Member

I like 'done()' better than 'next()'. It's focused on the current step instead of the step flow.

I thought of adding some predefined things like 'done()' to the default World (which can already be extended BTW, you don't have to overwrite it). But it would pollute its namespace. I like the idea of having a clean empty "userland" (I.e. World) in which end users do whatever they want/need. And that you can replace it with any other object.

Also, the explicit stepdef parameter is a neat reminder that you actually have to call it. Not calling the callback leads to bad things.

PS: sorry for this bad layout, iPad typing here.

});

this.Then( <REGEXP>, function(next) {
// express the regexp above with the code you wish you had
next.pending();
});
};
```


#### Examples

A few example apps are available for you to browse:

+ [Rails app serving features in the browser](https://github.com/jbpros/cucumber-js-example)
+ [Express.js app running features in the cli](https://github.com/olivoil/NodeBDD)
+ [Try cucumber.js in the browser](http://cucumber.no.de/)


A very young [example app](https://github.com/jbpros/cucumber-js-example) is now available.

## Setup for using in Node.js and running tests

Expand Down

0 comments on commit 1e29b6a

Please sign in to comment.