That was before the a-HA moment in which I began to realize that unit tests could more importantly verify the design of the application and the requirement of its components. What brings an even larger smile on my face is being able to squash bugs simply by providing different data or changing the impetus of an action in my tests; I can verify the bug and eliminate it, all without having to go through launching the application and going through n-number of User Actions just to see if what I changed fixed the issue at hand. Of course, yes, as a developer you still need to – nay, must – do your own QA before passing to QA, but I can offload the time required to go through all those User steps after I have verified that my modification is a logical fix and all other tests are still passing. Armed with this knowledge, I can now cause colleagues to have involuntary eye-rolls with a response to development issues as either: “What does the test say?” or “Modify the tests to the requirement and work from there.”
In any event, I still consider myself an early convert and haven’t figured everything out and am still tentative in spots and question the validity of writing a test for perhaps an implementation that is not really a requirement. But, it has brought a new level of fun and excitement to my development cycle and that is never a bad thing – especially as I see that it adds value.
If you sat through that jabbering about why i think unit testing brings value to application development, you are very kind, but now I want to address the real intent of this post: I thought it would be interesting to lay it out on the line and build a test-driven application over a series of posts. Writing something that is publicly accessible always drives me to question my knowledge (ps. buy my books!), but I would also like this series to invite criticism from readers so I can (selfishly) better myself. As well, perhaps I can impart some tidbit of wisdom to anyone following along – no guarantees
Grocery List Application
I decided to dedicate this series to building a test-driven application that would allow me to create a Grocery List. I figured it will be a small enough application to not get muddled down in large, complex requirements and several moving parts but still provide a real-life example of a CRUD-based application.
A Grocery List application is also something I have wanted to make for some time. We still, as a household, create a grocery list with pen and paper and take it in hand to the store. Nothing wrong with that, aside from the general user error of a) forgetting the list at home, and the user experience oversight of b) not being able to split up and cover parts of the list as a group. So, I thought it may be handy to have a web-based application that my family could add to, remove from and have available on the one thing we never leave the house without: attitudes. No. smartphones.
Since we are talking web-based, and specifically mobile-web, the current natural choice (barring snarky comments) is to build the application using HTML/JS/CSS. As well, I will assume we are developing against the latest available browsers and APIs; the application won’t (with my current mindset) be doing anything cutting edge, so will not require a specific distribution or OS.
The following is a list of libraries that will be used in developing the Grocery List application:
I am a huge proponent of AMD as part of application structure, with RequireJS as my library of choice. I have discussed it in more length in previous posts. I will not really cover the usage of RequireJS or concept of AMD much (if at all) in this series, so if you are unfamiliar I implore you to check them out; I will state that it provides a very convenient mechanism to separate responsibilities and dependencies (ie, modular development).
I chose Jasmine as my unit-test framework. In previous posts, I have supported the use of QUnit. I still love QUnit and admire its ease of use and set-up. However, over the past half-year, I had fallen in love with Jasmine and its BDD-style syntax. It provides (to me) more of means of defining behaviors of a system over testing attributes of an application’s components and lends to a nicer workflow of defining requirements and designing the application architecture. As well, just like QUnit, it is easy to integrate with RequireJS which is a requirement.
Jasmine does come with spies, but every now and then I find I need more when stubbing and mocking objects. I got familiar with Sinon when writing unit-tests in QUnit. I still continue to use it as it provides no conflicts with Jasmine and is familiar to me. There is a library out there called jasmine-sinon that provides Jasmine matchers for Sinon if you are interested; looks good – just trying to keep requirements low for the development of the Grocery List application.
If you are unfamiliar with stubs and mocks for testing, have a look at the Sinon docs.
Jasmine.Async provides a means of which to do asynchronous testing with Jasmine with ease. I have used it on a couple client-side projects and it really is worth it. Modelled after Mocha’s async test support, it is miles above the default async testing model available in Jasmine which basically suspends the test from progression until a flag is flipped in a watch() block.
So those are the libraries you will see being used when developing tests. From that list, RequireJS is the only library that will also be used in developing the actual Grocery List client-side application, which will most likely incorporate jQuery for ease in DOM traversal and AJAX, as well – it’s ubiquitous enough that I will not have to add noise to this series of posts by introducing another suite of libraries.
I have started a GitHub repo to track the progress of the application in this series: grocery-ls. Each blog post will have an associated tag, or tags, that will represent a snapshot of the repo at that point in time and which are accessible from the GitHub UI. The master branch will represent the current state of the application throughout the whole series.
I will be using a pre-defined set of terms and language to define a story and specification for a requirement when developing a test. These are mostly gleaned from the excellent article Introducing BDD by Dan North. I won’t be doing true BDD with the proper tooling, but rather more of a TDD with BDD characteristic and syntax as is provided from Jasmine, and will most likely complete the associated implementation from the specifications addressed in a single post so as to show test-to-implementation, instead of assembling all stories and specifications prior to implementation.
Alright, now that we have the pleasantries of intent and libraries used out of the way, let’s kick this off…
I had originally included working through the first story and suite of specifications for the Grocery List application in this post, but it got rather lengthy and though it started taking away some of the value (if any) the previous sections in this post provided. As such, I moved it out to the second installment of this series:
grocery-ls github repo
Part I – Introduction
Part II – Feature: Add Item
Part III – Feature: Mark-Off Item
Part IV – Feature: List-Item-Controller
Part V – Feature: List-Controller Refactoring
Part VI – Back to Passing
Part VII – Remove Item
Part VIII – Bug Fixing
Part IX – Persistence
Part X – It Lives!