I am completely new to D3JS and would like to understand the testing strategies for D3 JS.
To elaborate little more on question - consider I have a simple page that shows a line graph using a TSV file.
Java Script Code:
function LineManager() {} function LineProperties() { // Line Properties } LineManager.prototype.draw = function(properties) { // D3 code to draw a line with the given properties. }
I am not able to think of test cases to be considered for writing unit tests. Here is a sample test that I wrote ..
it("should throw an exception if line graph properties are not set.", function() { expect(lineManager.draw.bind(lineManager)).toThrow("Line Graph properties not set"); }); it("It should have single line chart", function() { lineManager.draw(properties); expect(lineManager.countLines()).toEqual(1); });
I have written unit tests to make sure the TSV file is getting generated correctly. But does it make sense to write a unit test to see if the data is getting rendered correctly? Isn't that more of a d3js unit test rather than unit test for my function?
So my question is - what tests should be considered for charts generated by d3js?
I think I got the answer to my own question. Will try to explain it here.
It is not possible to validate whether the graph is plotted correctly by JS function written using D3JS. For this we may have to use Phantom.js or similar framework as mentioned by Chrisopher. I was not worried about making sure D3JS is plotting graph correctly, as any ways it is D3JS functionality and my code can safely assume D3JS is doing its work.
My worry is more of whether the data passed to D3JS is correct and as per my requirement. It is very much possible to make sure the properties of the graph are set correctly by creating Spy objects. I am providing a sample unit test covering test cases for a JS code plotting a Circle using D3JS.
CircleManager.js
function CircleManager() {}; CircleManager.prototype.draw = function(radius) { var svg = d3.select("body") .append("svg"); svg.attr("width", 100) .attr("height", 100); var circle = svg.append("circle"); circle.style("stroke", "black") .style("fill", "white") .attr("r", radius) .attr("cx", 50) .attr("cy", 50); };
CircleManagerSpec.js
describe("draw", function() { it("Constructs an svg", function() { var d3SpyObject = jasmine.createSpyObj(d3, ['append', 'attr']); // Returns d3SpyObject when d3.select method is called spyOn(d3, 'select').andReturn(d3SpyObject); var svgSpyObject = jasmine.createSpyObj('svg', ['append', 'attr', 'style']); // Returns svgSpyObject when d3.select.append is called. d3SpyObject.append.andReturn(svgSpyObject); d3SpyObject.attr.andCallFake(function(key, value) { return this; }); svgSpyObject.append.andReturn(svgSpyObject); svgSpyObject.attr.andCallFake(function(key, value) { return this; }); svgSpyObject.style.andCallFake(function(key, value) { return this; }); var circleManager = new CircleManager(); circleManager.draw(50); expect(d3.select).toHaveBeenCalledWith('body'); expect(d3SpyObject.append).toHaveBeenCalledWith('svg'); expect(svgSpyObject.attr).toHaveBeenCalledWith('r', 50); expect(svgSpyObject.attr).toHaveBeenCalledWith('width', 100); expect(svgSpyObject.attr).toHaveBeenCalledWith('height', 100); expect(svgSpyObject.style).toHaveBeenCalledWith('stroke', 'black'); expect(svgSpyObject.style).toHaveBeenCalledWith('fill', 'white'); }); });
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With