A semi-opinionated wrapper for the mocha test suite.
Caffè Mocha
A semi-opinionated wrapper for the mocha test suite.
Caffè Mocha allows you to spend less time writing boilerplate and more time testing, and developing.
Getting Started
- Install Caffè Mocha:
yarn add --dev caffe-mocha # OR npm install -D caffe-mocha
- Set up your test cases:
// test/lib/my-methods.js import caffe from 'caffe-mocha' import myMethods from '../my-methods-module' const testCases = { sections: { 'Foo': { sections: { 'Bar': { cases: { 'bar should foo baz': { expectation: 'bazFoo', method: myMethods.bar, args: ['baz'], comparison: (a, b) => a === b }, 'bar should not foo qux': { expectation: 'qux', method: myMethods.bar, args: ['qux'], comparison: (a, b) => a === b, skip: true } } } } } } } caffe.run(testCases)
- Run your test cases:
mocha test/lib/my-methods.js # OR mocha --compilers js:babel-register test/lib/my-methods.js # FOR ES6 MODULES (ABOVE)
- DRY up your test cases with defaults:
// test/lib/my-methods.js import caffe from 'caffe-mocha' import myMethods from '../my-methods-module' const testCases = { defaults: { comparison: (a, b) => a === b }, sections: { 'Foo': { sections: { 'Bar': { defaults: { method: myMethods.bar }, cases: { 'bar should foo baz': { expectation: 'bazFoo', args: ['baz'] }, 'bar should not foo qux': { expectation: 'qux', args: ['qux'], skip: true } } } } } } } caffe.run(testCases)
Documentation
Tree Structure
A fully populated tree looks like this (with expected types):
const testCases = { defaults: { expectation: Any, method: Function, args: Array<Any>, comparison: Function || String, skip: Boolean }, sections: { 'Section 1': { defaults: { expectation: Any, method: Function, args: Array<Any>, comparison: Function || String, skip: Boolean }, sections: { 'Section 1 A': { defaults: { expectation: Any, method: Function, args: Array<Any>, comparison: Function || String, skip: Boolean }, sections: { /* ad infinum */ }, cases: { 'Case 1': { expectation: Any, method: Function, args: Array<Any>, comparison: Function || String, skip: Boolean } } } }, cases: { 'Case 1': { expectation: Any, method: Function, args: Array<Any>, comparison: Function || String, skip: Boolean } } } } }
Available Properties
The following properties are available:
defaults
An object that allows the user to define defaults in order to DRY up test cases, it is most useful for sub-sections that are all using the same method.
The available properties for the
defaults
object areexpectation
: The value that the output ofmethod
will be compared against.method
: The function/method that will acceptargs
, and return a value to compare againstexpectation
.args
: An array of arguments to be passed tomethod
.comparison
: The function/method that will compare the output ofmethod
andexpectation
. This can also be a string to easily do==
or>=
(etc) checks.skip
: A boolean that determines whether a section/case should be skipped (this will still output the test case name likedescribe.skip
orit.skip
does.)
A
defaults
object may exist at the root level.A
defaults
object may only exist at any level thatsections
orcases
exists.A
defaults
object may not exist at a level that is describing sections (see below)// This is not a valid configuration. This will create a `defaults` scope in mocha // but will not run any test cases as there is no `sections` or `cases` property. const testCases = { sections: { defaults: { method: myMethod } 'Foo': { /* etc */ } } }
A
defaults
object will merge all previous levels ofdefaults
.A
defaults
object deeper in the tree will overwrite any properties defined higher up.
sections
- An object that scopes test cases, or other sections.
- The available properties for the
sections
object are- Any valid key: This value may even be
sections
,defaults
, orcases
, as those properties can not exist at this level.
- Any valid key: This value may even be
- A
sections
object must exist at the root level. - A
sections
object may exist at any level that is not describing section names, as this would interpretsections
as the name of a literal section.
cases
- An object that contains all test cases for the current section.
- The available properties for the
cases
object are- Any valid key: This value may even be
sections
,defaults
, orcases
, as those properties can not exist at this level.
- Any valid key: This value may even be
- A
cases
object must not exist at the root level. - A
cases
object may only exist in a defined section.
Section
- An object that may define defaults, and test cases.
- The available properties for a section object are
defaults
: The object that defines default values for test cases.cases
: The object that defines test cases.
- A section object must not exist at the root level.
- A section object may only exist in a
sections
object. Any other location will cause the section to be discarded.
Case
- An object that defines a specific test case.
- The available properties for a case object are
expectation
: The value that the output ofmethod
will be compared against.method
: The function/method that will acceptargs
, and return a value to compare againstexpectation
.args
: An array of arguments to be passed tomethod
.comparison
: The function/method that will compare the output ofmethod
andexpectation
. This can also be a string to easily do==
or>=
(etc) checks.skip
: A boolean that determines whether a case should be skipped (this will still output the test case name likeit.skip
does.)
- A case object must not exist at the root level.
- A case object may only exist in a
cases
object. Any other location will cause the case to be discarded.
Methods
The following methods are exposed to the user:
caffe.run(testCases)
- This will generate and run the pre-defined test cases.
TODO
- Add handling for
-
before
-
beforeEach
-
after
-
afterEach
-
- Add ability to use async
done()
- Add
async
property to case anddefaults
object - Add
timeout
property to case anddefaults
object - Add
slow
property to case anddefaults
object - Add handling to pass
done
to the method
- Add
HomePage
https://github.com/taylorzane/caffe-mocha#readme