twolfson / sculptor

Library for sculpting framework/language agnostic BDD tests
MIT License
1 stars 0 forks source link

sculptor

Library for sculpting "framework/language agnostic" BDD tests

Sculptor is a test runner wrapper for any testing framework. Currently supported frameworks are: vows, mocha (planned), testling (planned), selenium+mocha (planned).

Tests are broken into two pieces:

// test/fruit.tests.json
{
  "An apple": {
    "is red": true,
    "and shiny": true
  }
}
// test/fruit.vows.js
{
  'An apple': function () {
    return new Apple();
  },
  'is red': function (apple) {
    assert.equal(apple.color, 'red');
  },
  'and shiny': function (apple) {
    assert(apple.shiny);
  }
}

This yields the following benefits:

Usage

Sculptor can be install via npm

sudo npm install -g sculptor

Test outlines and content should be stored within the test folder with the file formats:

*.tests.json # outline - e.g. test/shapes.tests.json
*.{{engine}}.js # content - e.g. test/shapes.vows.js for vows content

Then, tests can be run via the command line

sculptor

Documentation

CLI usage

Sculptor is run via the command line and can be configured as follows:

sculptor --engine mocha --dir src-test

--engine {{engine}} (Default: vows) - Test engine to run under (e.g. vows, mocha, testling, selenium+mocha). Only vows is available currently, all others are in development.

--dir {{dir}} (Default: test) - Directory to read in files and command files from.

--test-files {{testFiles}} (Default: test/*.tests.{js,json}) - Minimatch pattern to find test files by. This is the outline piece as described above. This means any files inside of test ending with .tests.js or .tests.json.

--command-files {{commandFiles}} (Default: test/*.{{engine}}.js) - Minimatch pattern to find command files by. This is the content piece as described above. If the engine is vows, this means any files inside of test ending with .vows.js.

--no-hints - Turn off hinting of when commands are not found. By default, this is disabled and you are notified Command could not be found: {{commandName}}.

Outline format

Outlines can either be an object or array of objects. Each object is run through the engine's interpretter (loading content into the outline) and added as a batch to be run. Then, all batches are run.

Asynchronous behavior (e.g. parallel vs series) will change depending on the engine.

Content format

Content files are expected to be an object with strings that match the test names and values which are functions to run at each level.

In the case that keys do not line up, Sculptor has been designed to notify you via a console.log (see CLI usage#no-hints).

Aliasing/Chaining commands

A bonus feature is the ability to alias and chain commands. Aliasing is done by using a string of the command you would like to alias.

{
  'A circle': function () {
    return new Circle();
  },
  'A round object': 'A circle'
}

Chaining is performed by using an array of strings. These strings are broken out into a nested object for interprettation by the engine.

{
  'A banana': function () {
    return new Banana();
  },
  'when peeled': function (banana) {
    return banana.peel();
  },
  'A peeled banana': ['A banana', 'when peeled']
}

Warning: Chaining at the leafs of tests can be confusing. Instead of the chain being asserted, they are run as nested objects meaning only the last item in the chain is an assertion.

Examples

An implementation of Sculptor can be found within the test folder.

A pre-Sculptor implementation can be found within node-jsmin-sourcemap.

Additionally, to make my life easier, I use an object between my topics. This makes them order agnostic and easily chainable.

// Outline
{
  'a': {
    'b': {
      'some assertion': true
    }
  },
  'b': {
    'a': {
      'some assertion': true
    }
  }
}

// Content
{
  'a': function (topic) {
    topic = topic || {};
    topic.a = 1;
    return topic;
  },
  'b': function (topic) {
    topic = topic || {};
    topic.b = 1;
    return topic;
  },
  'some assertion': function (topic) {
    assert.equal(topic.a, topic.b);
  }
}

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint your code using grunt and test via npm test.

License

Copyright (c) 2012 Todd Wolfson Licensed under the MIT license.