Now that we have a code base written in a testable way, let's automate those tests so that we do not have to perform them manually and can continue to code and refactor with ease.
If you look at the spec/viz_spec.js file, you will note some common patterns when unit testing. The following code is written with a JavaScript unit-testing framework called Jasmine and leverages Karma to execute the tests. You can learn more about the Jasmine syntax, assertions, and other features at http://jasmine.github.io/1.3/introduction.html.
The Bootstrap project has everything you need to start testing quickly.
The first step is to start our Karma test runner with this line of code:
node_modules/karma/bin/karma start
This runner will watch every edit of the viz.js file or the viz_spec.js file. If any changes are detected, it will automatically rerun every test suite and provide the output on the console. If all the tests pass, then the output will be all green. If something fails, you will receive a red warning message:
'use strict';
describe('Visualization: Stacked', function () {
var viz;
var data = [
{"category": "gold", "cost": "10", "sales": "60"},
{"category": "white", "cost": "20", "sales": "30"},
{"category": "black", "cost": "100", "sales": "140"}
];
Create some test data to test your D3 data manipulation functions. The preceding describe syntax defines the test harness you are about to execute:
beforeEach(function() {
viz = d3.charts.viz()
.height(600)
.width(900)
.margin({top: 10, right: 10, bottom: 10, left: 10});
});
Before every test run, create a new instance of the D3 visualization with some default setters:
it ('sets the profit', function() {
var profits = viz.profit(data);
expect(profits.length).toBe(3);
expect(profits[0].profit).toBe(50)
});
This is our first test case! In this test, we asserted that we are getting a new array from our test data, but with an additional profit attribute. Remember that we created the function to have no side effects and to be a small unit of work. We will reap the fruits of our labor with this easy-to-test method. Just as we did earlier, we will test the list of categories now:
it ('returns a list of all categories', function() {
var categories = viz.categories(data);
expect(categories.length).toBe(3);
expect(categories).toEqual([ 'gold', 'white', 'black' ]);
});
Calculate the maximum profit, as follows:
it ('calculates the profit max', function() {
var profits = viz.profit(data);
expect(viz.profitMax(profits)).toEqual(50);
});
The following are additional example tests to validate that the height/width, bearing in mind the margins, is working properly from our base.js function:
it ('calculates the height of the chart box', function() {
expect(viz.h()).toBe(580);
viz.height(700); // change the height
viz.margin({top: 20, right: 10, bottom: 10, left: 10})
expect(viz.h()).toBe(670);
});
it ('calculates the width of the chart box', function() {
expect(viz.w()).toBe(880);
viz.height(700); // change the height
viz.margin({top: 10, right: 10, bottom: 10, left: 20})
expect(viz.w()).toBe(870);
});
As an experiment, try adding new test cases or editing the existing one. Watch the test runner report different results.