A Beginner's Guide to Test Driven Development, Part 1

JavaScript testing frameworks libraries

Programming and teaching have a lot in common. In some ways, teaching students how to balance chemical equations is a lot like teaching a computer to do so: you have to have a clearly defined goal, create a basic plan, differentiate to account for differing strengths and weaknesses (cough Internet Explorer cough), determine if you were succesful, and modify your plans if you weren’t.

Professionals in both fields have also devised outcome-focused frameworks for developing high-quality products. Teachers call this backward design; programmers call it test driven development. Both strategies require one to have a clear idea of their overarching goal, as well as their intermediate objectives. This allows teachers and programmers to then create a series of assessments, or test, to determine if their plans are working as they implement them, and change course if they are not.

I had been using backwards design for years as a teacher, so I am already quite familiar with the basic premises of test driven development:

  1. Write a failing test (one that your program/ students cannot yet pass)
  2. Add just enough code (or instruction) so the program/students can pass the test.
  3. Refactor (or reteach) where necessary.

However, while I had collected a wide array of tools with which to implement backwards design as a teacher, I am just beginning to become familiar with those available to programming.

One way of implementing TDD is in the browser using Mocha, Chai, and Sinon. If you do a quick google search of each of these, you will learn that Mocha is a “testing framework”, Chai is an “expectation library,” and Sinon is a…. well, let’s call it a “virtual environment library.” Unfortunately, if you’re new to programming none of that means anything to you. If you’re like me, when you first read each of those “definitions,” you may have thought to yourself, “Ok, but what is a testing framework? Actually, what’s a framework?? And what is the difference between a library and a framework?”

Defining a Framework

Seattle library framework inside

The everyday definition of framework is a skeletal structure designed to support or enclose something. Many high school English teachers provide their students with essay frameworks like this one to help students organize their thoughts into a coherent structure. Most essay frameworks specify that the student should include an introductory paragraph, three to five body paragraphs, and a conluding paragraphs. In earlier grades, these frameworks may be even more specific and enforce additional organizational elements within individual paragraphs. Students then simply fill in the template with their content. Most teachers will mark down students who do not follow this structure until the student is advanced enough to write an organized essay without the provided framework.

This is not that different from what a programming framework does; from Wikipedia, a software framework, “is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate development of software applications, products and solutions.” In other words, it makes it easier and faster for you to write your program by doing a lot of the work for you by providing one or more libraries, scripts, reference documentation, and other related resources. Not only that, but it also enforces a standard structure to follow that helps keep your code organized. Users can extend the functionality of the framework, but should not modify its code.

Because testing is such a fundamental part of programming, Mocha sets up the environments within when you will be completing your tests. For example, it will generate an html reporter that renders in an easy-to-read format in the browser.

Libraries

Libary booksLibrary Pengo”. Licensed under CC BY-SA 3.0 via Wikimedia Commons.

At first, it can be difficult to differentiate between a framework, and a library. Like a framework, a library provides us with a set of reusable code structures to take some of the redundancy out of coding. However, libraries only provide a collection of modular code with which to write our own programs. They do not dictate the overall structure of the program itself. Going back to our essay analogy, a software library is more like the set of high level vocabulary terms the teacher encourages students to use in their essay.

Chai and Sinon are both software libraries. Each provide a collection of related modular code that can be used from within the Mocha framework. When writing our tests, we need to be able to decide if our program is actually doing what we want. Chai essentially gives us a set of tests we can apply to our program, while Sinon allows us to trick our program into running in a fake environment so we can spy on it.

The tests Chai and other, similar libraries, use are called assertions. An assertion simply compares what we want our program to do, to what it actually is doing. As such, they return a boolean value: if our programm isworking correctly, the assertion evaluates to true, and it passes the test.

Sinon uses spies, stubs, and mocks to keep track of everything our program is doing and allow it to run without the actual dependencies it will need. A spy records function arguments, return values and other data used and created by our program. Stubs are basically spies with super powers. Not only do they keep track of the data related to our program, they also allow us to fake functionality so the rest of our system thinks the program is running normally. Finally, a mock combines the concepts of spies, stubs, and assertions all together. I will go into these ideas more in a later blog post, as they are difficult to conceptualize without detailed examples.

So, now we know what TDD is, why we would use it, and how our testing frameworks and libraries work together to allow us to implement it. Next up I’ll explain step-by-step how to actually set up a testing suite using a concrete JavaScript example.

Written on July 9, 2015