I'm a big fan of BDD for integration tests and have started looking at using them from unit tests as well. From other questions (e.g. this one 1), I can see that people generally consider it acceptable to write BDD style unit tests. However, I haven't seen any examples of unit tests using BDD language. Seeing some concrete examples would help me get my head around it much better.
I'm wondering how to use BDD when the test is examining low level system behaviour that a user would not experience. For an integration/view test, I'd do something like this:
describe('Given that an author is using the question editor with a choice matrix question open ', function () {
describe('When the author clicks the 'Allow Multiple Responses' switch', function () {
it('Then the question preview should change from radio buttons to checkboxes', function () {
expect(....);
});
});
});
But what about if I'm testing the functionality of a low level method? Is it an anti-pattern if I'm trying to test a low level unit that a user would never touch it? For example, if I want to use Jasmine to test the functionality of a method called isCellShadedByAuthor(), my best guess is to do something like this:
describe("Given that the cell is in the response area not on the author side", function () {
it("When the cell is an author shaded cell, then isCellShadedByAuthor should return true", function () {
expect(isCellShadedByAuthor(1, 3)).toBeTruthy();
});
));
I guess another way to approach this situation is to try to elevate the test to a view test where I'd assert based on the presence of a CSS class rather than directly asserting on the return value of isCellShadedByAuthor(). This would reduce the coupling of the test to the implementation details.
For example, I could do ​
describe("Given that the cell is in the response area not on the author side", function () {
it("When the user hovers over an author shaded cell, then the cell should have the hover class", function () {
var cell = $('shading-cell[data-attribute-x="1"][data-attribute-y="1"]);
expect(cell.hasClass('hover-disabled')).toBeTruthy();
});
));
I'm not sure if you question pertains purely to JavaScript, but I have certainly used BDD unit tests for Java projects at previous employers. We made use of the BDDMockito class in the Mockito library.
We actually created a very simply BDD unit test template in our IDE that we all shared.
public void shouldDoFooOnBar() {
//given (perform setup here)
<code to define state of system>
//when
<single call to code under test>
//then
<code to assert expectations>
}
We found this gave our tests a nice consistent structure that was easy to read.
Here is a concrete example from Mockito:
public void shouldBuyBread() throws Exception {
//given
given(seller.askForBread()).willReturn(new Bread());
//when
Goods goods = shop.buyBread();
//then
assertThat(goods, containBread());
}
It is worth mentioning that we were also using BDD at the integration test level, but for this we were using FitNesse.
Related
I am constructing a simple linechart using JFreechart API.. Can anyone let me know how to unit test it using mockito. I am still kind of new to do unit testing framework. Dont really know how it works
public LineChart(String applicationTitle, String chartTitle) {
super(applicationTitle);
// Create the dataset
CategoryDataset dataset = new DataSet().createDataLineSet();
JFreeChart chart = createChart(dataset, chartTitle);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(CHART_WIDTH,
CHART_HEIGHT));
setContentPane(chartPanel);
}
/**
* Creates a sample chart
*
* #param dataset
* ,the chartTitle
*
* #return The chart.
*/
public JFreeChart createChart(CategoryDataset dataset, String chartTitle) {
// TODO Auto-generated method stub
// create the chart
JFreeChart chart = ChartFactory.createLineChart(chartTitle, // chart
// title
categoryAxisLabel, // category axis label
valueAxisLabel, // value axis label
dataset, // data
PlotOrientation.VERTICAL, // chart orientation
true, // include legend?
true, // include tooltips?
false // URLs?
);
return chart;
}
The way you've structured it, this is a particularly hard class to unit test, and I'm not sure how much value unit testing would provide. Is this code for a school or work project with a "unit test all your code" directive?
First, a clarification based on your tags: Mockito is not a unit testing framework.
junit is a unit testing framework that allows you to write classes with methods that exercise classes. Using exceptions, as well as calls to Assert.assertEquals, Assert.assertTrue, and Assert.fail (for instance) you can write tests with minimal boilerplate. Reading JUnit's Getting Started page may help.
mockito is a mocking framework, which allows you create mocks and stubs of objects and verify that you're system under test is interacting with its collaborators correctly. Though it's preferable to unit test just by checking the return value of a method call or the state of the system after your test, certain classes require interaction with external systems. The first few numbered items of the Mockito documentation may help.
At least three things make your class hard to test using mocks and JUnit:
Your system under test is directly calling constructors. This gives you very little opportunity to substitute in simpler implementations or mocks for test.
The collaborator you're interacting with (JFreeChart API) is designed for GUIs. It can be hard to test GUI-oriented classes in a headless, reproducible way, which are two typical aspects of unit tests.
The collaborator is third-party software, which can be dangerous to mock. Mocking relies on some implementation details (like whether methods are public or final) that can be dangerous for code that's not directly under your control.
Remember also that it is an anti-pattern to test the implementation—unit tests are designed to check that your code produces the correct results. Looking at the code that you posted, I'm not sure what I would test there.
On the other hand, if you have a separate part of the project that loads and processes numeric data to feed into your chart, it would be very straightforward and useful to produce a JUnit test that takes in data from a sample file, runs it through the loader/processor you write, and ensures that it produces the correct numbers that you've worked out and confirmed by hand. The continued passing of that test is some guarantee that your code still works as expected, even if the implementation of your loader/processor were to change.
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.
I think you should consider this: http://busypeoples.github.io/post/testing-d3-with-jasmine/
And it really seems to make sense. I have read the others' answers but I am little bit disagree with them. I think we not only check if right function is called or not but we can check much more than that. Checking only some function call are good at unit testing level but not enough. Such test cases written by developer will be based on developer's understanding like these functions are called or not. But whether these methods should be called or not, this thing can be only checked by going at another level because unlike other work, here are code is making something not returning something that can be just checked and make sure everything is correct.
We obviously don't need to check whether D3 is doing its work correctly or not. So we can use D3 inside our testing code. But D3 renders SVG and we can check things like if svg have elements where expected. Again it is not going to test whether SVG is showing and rendering properly or not. We are going to check if SVG have elements which are expected and they are set as expected.
For example:
If this is bar chart, we can check the number of bars. As in example in above link here it is check that.
// extend beforeEach to load the correct data...
beforeEach(function() {
var testData = [{ date: '2014-01', value: 100}, { date: '2014-02', value: 140}, {date: '2014-03', value: 215}];
c = barChart();
c.setData(testData);
c.render();
});
describe('create bars' ,function() {
it('should render the correct number of bars', function() {
expect(getBars().length).toBe(3);
});
it('should render the bars with correct height', function() {
expect(d3.select(getBars()[0]).attr('height')).toBeCloseTo(420);
});
it('should render the bars with correct x', function() {
expect(d3.select(getBars()[0]).attr('x')).toBeCloseTo(9);
});
it('should render the bars with correct y', function() {
expect(d3.select(getBars()[0]).attr('y')).toBeCloseTo(0);
});
});
// added a simple helper method for finding the bars..
function getBars() {
return d3.selectAll('rect.bar')[0];
}
Some people probably gonna say that we are going to use D3 inside testing code? Again we should remember that purpose of test writing here is not to test D3 but our logic and SVG code that is compiled in response to our code.
This is just a way and jasmine is something that is helping us in writing test, you can also go into more detail and in different scenarios. You can make domain and check datapoints width height to cross check if they result into data which were given to render.
I think I am clear if not then check this link : http://busypeoples.github.io/post/testing-d3-with-jasmine/
Here write of this article have explained things in detail with how you can use jasmine.
Also I think I am still gone into detail. If only unit testing is required at different js functions level then there are a lot more things which can be tested without going into elements detail.
Testing strategy
The strategy I end up using to test d3.js code is to create helper functions to manage my data and settings. I then unit test these functions. So for charts I would check every functionality dealing with data, every function to set width, legends etc...
Concerning drawing functions it can get trickier but with testing frameworks such as buster.js it can be quite easy to implement these too. A good way of testing a chart would be to count the number of bars/lines in the page, check that legends are printing etc.
I would not try to check that the chart is visually the same because visually checking that the end result is the same is easiest. However, when writing the drawing functions, one should be very attentive to what happens on updates (will changing the data draw twice as many lines? are selectors right? ...)
Javascript testing
A great book on javascript testing is: Test Driven Javascript Development. It provides lots of examples and strategies to test javascript code. Most of them can be directly applied to d3.js code.
Tools
I recently looked for solutions for unit testing d3.js code and I ended up using the following tools:
buster.js
Buster.js is a very complete framework for unit testing javascript code in multiple browsers.
phantom.js
Phantom.js is a headless WebKit scriptable with a JavaScript API.
This means that it makes it easy to run automated tests on javascript without needing to use browsers such as chrome, safari etc..
EDIT: I would now use jasmine for unit testing and selenium (through the Saucelabs service maybe) for end to end testing.
Probably worth mentioning Jest snapshot testing. Jest/snapshots are popular for React UI components, as they're also difficult to test. With D3 you could generate an SVG take a snapshot and verify as your codebase evolves that you continue to generate the same output.
function makeChart(id, dataset) {
const chart = d3.select(id)
.append("svg")
.selectAll("circle")
.data(dataset)
.enter().append("circle")
.style("stroke", "gray")
.style("fill", "black")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 20);
return chart;
}
it('renders correctly', () => {
const myChart = makeChart('#example', [1,2,3])
expect(myChart.node()).toMatchSnapshot();
});
This test is untested
A snapshot can be any output a string "Foo Bar" a JSON object {foo: "bar"} etc.
Basically you have to run a test once that contains .toMatchSnapshot. Jest will then manage the generation and store a copy that it'll compare in future tests.
The concept is similar to VCR in Ruby testing. Record and replay.
I've read tons of articles, seen tons of screencasts about TDD, but I'm still struggling with using it in real world project. My main issue is I don't know where to start, what test should be the first one.
Suppose I have to write client library calling external system's methods (e.g. notification).
I want this client to work as follows
NotificationClient client = new NotificationClient("abcd1234"); // client ID
Response code = client.notifyOnEvent(Event.LIMIT_REACHED, 100); // some params of call
There is some translation and message format preparation behind the scenes, so I'd like to hide it from my client apps.
I don't know where and how to start.
Should I make up some rough classes set for this library?
Should I start with testing NotificationClient as below
public void testClientSendInvalidEventCommand() {
NotificationClient client = new NotificationClient(...);
Response code = client.notifyOnEvent(Event.WRONG_EVENT);
assertEquals(1223, code.codeValue());
}
If so, with such test I'm forced to write complete working implementation at once, with no baby steps as TDD states. I can mock out sosmething in Client but then I have to know this thing to be mocked upfront, so I need some upfront desing to be made.
Maybe I should start from the bottom, test this message formatting component first and then use it in right client test?
What way is the right one to go?
Should we always start from top (how to deal with this huge step required)?
Can we start with any class realizing tiny part of desired feature (as Formatter in this example)?
If I'd know where to hit with my tests it'd be a lot easier for me to proceed.
I'd start with this line:
NotificationClient client = new NotificationClient("abcd1234"); // client ID
Sounds like we need a NotificationClient, which needs a client ID. That's an easy thing to test for. My first test might look something like:
public void testNewClientAbcd1234HasClientId() {
NotificationClient client = new NotificationClient("abcd1234");
assertEquals("abcd1234", client.clientId());
}
Of course, it won't compile at first - not until I'd written a NotificationClient class with a constructor that takes a string parameter and a clientId() method that returns a string - but that's part of the TDD cycle.
public class NotificationClient {
public NotificationClient(string clientId) {
}
public string clientId() {
return "";
}
}
At this point, I can run my test and watch it fail (because I've hard-coded clientId()'s return to be an empty string). Once I've got my failing unit test, I write just enough production code (in NotificationClient) to get the test to pass:
public string clientId() {
return "abcd1234";
}
Now all my tests pass, so I can consider what to do next. The obvious (well, obvious to me) next step is to make sure that I can create clients whose ID isn't "abcd1234":
public void testNewClientBcde2345HasClientId() {
NotificationClient client = new NotificationClient("bcde2345");
assertEquals("bcde2345", client.clientId());
}
I run my test suite and observe that testNewClientBcde2345HasClientId() fails while testNewClientAbcd1234HasClientId() passes, and now I've got a good reason to add a member variable to NotificationClient:
public class NotificationClient {
private string _clientId;
public NotificationClient(string clientId) {
_clientId = clientId;
}
public string clientId() {
return _clientId;
}
}
Assuming no typographical errors have snuck in, that'll get all my tests to pass, and I can move on to whatever the next step is. (In your example, it would probably be testing that notifyOnEvent(Event.WRONG_EVENT) returns a Response whose codeValue() equals 1223.)
Does that help any?
Don't confuse acceptance tests that hook into each end of your application, and form an executable specifications with unit tests.
If you are doing 'pure' TDD you write an acceptance test which drives the unit tests that drive the implementation. testClientSendInvalidEventCommand is your acceptance test, but depending on how complicated things are you will delegate the implementation to multiple classes you can unit test separately.
How complicated things get before you have to split them up to test and understand them properly is why it is called Test Driven Design.
You can choose to let tests drive your design from the bottom up or from the top down. Both work well for different developers in different situations. Either approach will force to make some of those "upfront" design decisions but that's a good thing. Making those decisions in order to write your tests is test-driven design!
In your case you have an idea what the high level external interface to the system you are developing should be so let's start there. Write a test for how you think users of your notification client should interact with it and let it fail. This test is the basis for your acceptance or integration tests and they are going to continue failing until the features they describe are finished. That's ok.
Now step down one level. What are the steps which need to occur to provide that high level interface? Can we write an integration or unit test for those steps? Do they have dependencies you had not considered which might cause you to change the notification center interface you have started to define? Keep drilling down depth-first defining behavior with failing tests until you find that you have actually reached a unit test. Now implement enough to pass that unit test and continue. Get unit tests passing until you have built enough to pass an integration test and so on. You'll eventually have completed a depth-first construction of a tree of tests and should have a well tested feature whose design was driven by your tests.
One goal of TDD is that the testing informs the design. So the fact that you need to think about how to implement your NotificationClient is a good thing; it forces you to think of (hopefully) simple abstractions up front.
Also, TDD sort of assumes constant refactoring. Your first solution probably won't be the last; so as you refine your code the tests are there to tell you what breaks, from compile errors to actual runtime issues.
So I would just jump right in and start with the test you suggested. As you create mocks, you will need to create tests for the actual implementations of what you are mocking. You will find things make sense and need to be refactored, so you will need to modify your tests as you go. That's the way it's supposed to work...
I'm writing an application using an MVC framework which takes care of a lot of the boilerplate wiring of our system. Specifically - application is written in Flex, using the Parsley MVC framework. However, the question is not language specific.
In my Presentation Model / Code-Behind / View-Controller (whatever you want to call it), I might have something like this:
[Event(name="attemptLogin",type="com.foo.AttemptLoginEvent")]
[ManagedEvents["attemptLogin"]
public class LoginViewPM {
public function attemptLogin(username:String,password:String):void
{
dispatchEvent(new AttemptLoginEvent(username,password));
}
}
Then, elsewhere in my system, code which responds to this, would look like this
public class LoginCommand {
[MessageHandler]
public function execute(attemptLoginEvent:AttemptLoginEvent):void {
// Do login related stuff
}
}
It's important to note that within Flex / Actionscript, Metatags are not checked by the compiler. For example:
[Event(name="attemptLogin",type="com.foo.AttemptLoginEvent")]
[ManagedEvent["attemptLogin"] // Spelling mistake - metatag is ManagedEvents
public class LoginViewPM {
and
[Event(name="attemptLogin",type="com.foo.AttemptLoginEvent")]
[ManagedEvent["attemtLogin"] // Spelling mistake - event name is wrong
public class LoginViewPM {
In the above two examples, the framework will fail. In the first example it fails silently (because the metatag is incorrect - hence the framework is never engaged). In the second example, we get some runtime logging that partially alerts us that things are wrong.
Given this, what is a pragmatic level of unit testing for the attemptLogin() method on the PM, with regard to the MVC framework's duties? Ie:
Should I:
Test that the AttemptLoginEvent is managed by the MVC framework
Test that the LoginCommand gets invoked by the framework when the event is dispatched.
In other container / framework environments, I tend not to write tests that exercise the responsibilities of the frameworks, as (IMHO) this leads to brittle tests. However, given the lack of compiler checking, in this case it may seem warrented.
Thoughts?
If you think about it, you're not really testing the responsibilities of the framework as much as you are testing how well your coders can type.
However, if the same coder who wrote the event also writes the test, and if the event name is something that will not be updated frequently, then you could probably skip it, since any typos would most likely be caught while the test is being written.
What you want to test sounds like integration testing. If you want a unit test, you have to define what your unit is.
If you want to test your eventing, mock the event receiver and find out whether the mock has been called afterwards.
public class MockLoginCommand : ICommandReceiver {
public bool BeenCalled { get; set; }
[MessageHandler]
public function execute(attemptLoginEvent:AttemptLoginEvent):void {
BeenCalled=true;
}
}
etc.
I'm looking for tidy suggestions on how people organise their controller tests.
For example, take the "add" functionality of my "Address" controller,
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Add()
{
var editAddress = new DTOEditAddress();
editAddress.Address = new Address();
editAddress.Countries = countryService.GetCountries();
return View("Add", editAddress);
}
[RequireRole(Role = Role.Write)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(FormCollection form)
{
// save code here
}
I might have a fixture called "when_adding_an_address", however there are two actions i need to test under this title...
I don't want to call both actions in my Act() method in my fixture, so I divide the fixture in half, but then how do I name it?
"When_adding_an_address_GET" and "When_adding_an_address_POST"?
things just seems to be getting messy, quickly.
Also, how do you deal with stateless/setupless assertions for controllers, and how do you arrange these wrt the above? for example:
[Test]
public void the_requesting_user_must_have_write_permissions_to_POST()
{
Assert.IsTrue(this.SubjectUnderTest.ActionIsProtectedByRole(c => c.Add(null), Role.Write));
}
This is custom code i know, but you should get the idea, it simply checks that a filter attribute is present on the method. The point is it doesnt require any Arrange() or Act().
Any tips welcome!
Thanks
In my opinion you should forget about naming your tests after the methods you're testing. In fact testing a single method is a strange concept. You should be testing a single thing a client will do with your code. So for example if you can hit add with a POST and a GET you should write two tests like you suggested. If you want to see what happens in a certain exceptional case you should write another test.
I usually pick names that tell a maintainer what he needs to know in Java:
#Test public void shouldRedirectToGetWhenPostingToAdd(){
//...
}
You can do this in any language and pick any *DD naming convention if you like, but the point is that the test name should convey the expectations and the scenario. You will get very small test this way and I consider this a good thing.
Well, 13 months later and no answers. Awesome.
Heres what i do now:
/tests/controllers/address/add/get.cs
/tests/controllers/address/add/valid.cs
/tests/controllers/address/add/invalid.cs