A Short Lecture On The Value And Practice of Unit Testing
Test and Monitor | Posted September 05, 2012

Here's a great video that showed up on Reddit last week about Automated Testing and Inversion of Control. In an easy-to-follow lecture, Curtis Lassam explains how and why you should be unit testing your software. We've also summarized the points in the video as text below.


Automated tests are a spectacularly useful coding tool. Start with a thesis, bam.

Unit tests are so important that they should be a first class language construct. Here's why:

1. Regressions

Even in a well-designed system, code still interacts with other code. I mean, it has to. We do our best to keep the interactions to a small, well-defined minimum, but code that doesn't interact with anything at all doesn't usually do anything at all.

Code in a single class, for example, interacts with other code in that same class. And yes, when you make changes in the code, you can break things. Things that other people wrote; things that you wrote a few days ago and forgot about; things that you wrote just now and didn't think about because you're dumb.

If there are automated tests to check that everything is still working as promised, then you can catch these things before something bad happens. And now that you have the safety net of a good set of automated tests, you can change the code with impunity.

2. Documentation

As much as the combination of function signature and documentation are supposed to be enough to make the intent of your code completely and perfectly clear, it doesn't often communicate the best way to use your code.

Tests right in the functions documentation that manage to both clarify how the function is used, and automatically test the function in the same space. Even if unit tests aren't in the documentation, though, they still serve as live operational examples of how to use your code.

Those are some of the benefits of unit testing, now let's talk about how to do it.

1. Find a unit testing framework.

A unit test framework exists for developers of every stripe: Java, C#, Python, C++, the one guy who programs in Haskell, Ada, Visual FoxPro.

The two features that characterize unit testing frameworks are the ability to run every unit test in your solution and see the results, and helper functions providing assertion logic.

2. Once you have tests, run them regularly

Talk to your build guy. If you don't have a build guy, run a script to check out your code base, and run the tests periodically to let you know when somebody has checked in code that's broken a test. Do check in code that breaks tests. Punish people who do with silly hats.

3. Only Test the Thing You're Testing

Focus on testing individual components, individual classes in isolation. This is a unit test. But with every class having some kind of dependency, how do we isolate that class for testing?

Inversion of control and dependency injection are two methods. Watch the video for more information on this.

4. Mocking and Stubbing

You can mock out things that supply non-deterministic results. You can mock out things that have states that are a pain to reproduce. You can mock out things that are slow. You can even mock out things that don't exist yet.

Now, you don't have to mock out every dependency from every class that you write. If the behavior of the dependency is reasonably simple and itself well tested, mocking may not be necessary. Definitely keep it in mind, though.

5. Pitfalls

Remember that unit tests are part of your code base, too. They have a development cost, a maintenance cost, and they don't directly produce value for your users. Going crazy with overzealous testing and mocking might produce code that's light on bugs, but expensive to produce in change.

You don't want to codify implementation details into your tests. That's a mistake. If you reach the point where you feel like you might need unit tests for your unit tests, you've gone too far.