Data-driven unit testing for JavaScript.
This module provides a simple but flexible way to create data-driven tests in JavaScript. It works with the most popular JavaScript testing frameworks: mocha, jasmine, and jest.
Install Sazerac as an npm module and save it to your package.json
file as a development dependency:
npm install sazerac --save-dev
Import the test
and given
helper functions into your project:
import { test, given } from 'sazerac'
Let's say you have a function isPrime()
. When given a number, it returns true
or false
depending on whether the number is a prime number.
function isPrime(num) {
for(var i = 2; i < num; i++) {
if(num % i === 0) return false;
}
return num > 1;
}
If you're using a framework like jasmine, your tests might look something like this:
describe('isPrime()', () => {
describe('when given 2', () => {
it('should return true', () => {
assert.isTrue(isPrime(2))
})
})
describe('when given 3', () => {
it('should return true', () => {
assert.isTrue(isPrime(3))
})
})
describe('when given 4', () => {
it('should return false', () => {
assert.isFalse(isPrime(4))
})
})
// and more ...
})
It's a lot of code to write for only 3 test cases and such a basic function!
The same tests can be defined with Sazerac as follows:
test(isPrime, () => {
given(2).expect(true)
given(3).expect(true)
given(4).expect(false)
})
Sazerac runs the describe
and it
functions needed for these test cases. It adds reporting messages in a consistent format based on the input and output parameters. For this example, the test report ends up looking like this:
isPrime()
when given 2
✓ should return true
when given 3
✓ should return true
when given 4
✓ should return false
test()
sets the function you want to test. given()
creates a test case by defining the arguments that will be passed to your function.
test(mySumFunction, () => {
var t = given(1, 2, 3)
})
The test case returned by given
provides functions for defining your test case.
Sets the expected return value for a test case. Uses assert.deepEqual
from the chai assertion library.
t.expect(6)
Sets a message for the reporter to describe the test case. This message will be passed to the describe
function when the tests run.
t.describe('when called with a set of numbers')
Sets a message for the reporter to describe the test expectation. This message will be passed to the it
function when the tests run.
t.should('should return the sum of the numbers')
Adds an assertion for the test case. message
describes this assertion, and will be passed to the it
function when tests run. assertFunction
is called with the actual return value of the executed test function.
t.assert('should set the value of the sum property to 6', (actualReturnValue) => {
// use any assertion library here
assert.equal(actualReturnValue.sum, 6)
})
Multiple assertions can be added to a single test case
t.assert('should set a sum property', (actualReturnValue) => {
assert.hasProperty(actualReturnValue, 'sum')
}).assert('should set the value of the sum property to 6', (actualReturnValue) => {
assert.equal(actualReturnValue.sum, 6)
})
All test case functions can be chained, in any order.
test(mySumFunction, () => {
given(1, 2, 3)
.expect(6)
.describe('when called with a set of numbers')
.should('should return the sum of the numbers')
})
If you have multiple test case inputs with the same expected return value, they can be grouped with the forEach(cases)
function:
import { test, given, forEach } from 'sazerac'
test(isPrime, () => {
const primes = [ given(2), given(3), given(5), given(7) ];
const nonPrimes = [ given(1), given(4), given(6), given(8) ];
forCases(primes).expect(true)
forCases(nonPrimes).expect(false);
});
forCases
returns an object with the same functions that can be applied to an individual test case: expect
, describe
, should
, and assert
Sazerac formats describe
and it
messages based on given parameters and the expected return value:
test(myFunction, () => {
given(1, 2, 3).expect(true)
})
/*
report output:
myFunction()
when given 1, 2, and 3
✓ should return true
*/
For custom formatted messages, sazerac uses https://github.com/alexei/sprintf.js.
Custom formatting can be applied to .describe
messages using given parameters:
test(addTwoNumbers, () => {
given(2, 3).expect(5).describe('%s plus %s')
})
/*
report output:
addTwoNumbers()
2 plus 3
✓ should return 5
*/
Same for .should
messages, but expected value is used:
test(addTwoNumbers, () => {
given(2, 3).expect(5).describe('%s plus %s').should('equals %s')
})
/*
report output:
addTwoNumbers()
2 plus 3
✓ equals 5
*/