Unit Testing with JavaScript — Part 1: Best Practices
Despite the fact that unit testing can add considerable value to the quality of your code, it can do more harm than good, on the long run, if you do not implement it correctly.
It all depends on the quality of the tests you design. And it, in turn, depends on how well you understand the basic principles of “unit testing“.
Navigation
This is Part 1 of a 4-part Series on JavaScript Unit Testing. Here are links to all of the parts:
- Unit Testing with JavaScript — Part 1: Best Practices
- Unit Testing with JavaScript — Part 2: Preparation
- Unit Testing with JavaScript — Part 3: Getting Your Feet Wet
- Unit Testing with JavaScript — Part 4: Automation
What is a Unit Test
First things first. Let us start with a definition of a unit test:
In computer programming, unit testing is a method by which individual units of source code are tested to determine if they are fit for use.
A unit is the smallest testable part of an application. In procedural programming a unit may be an individual function or procedure.
The difference between a good and a bad unit test cannot be easily seen. Additionally, the methodology of learning to write good unit tests is far from obvious. Even being a rock-star developer with years of experience won’t magically make you create better-than-average unit tests unless you learn to change your habits.
Unit Testing is not Integration Testing
There is a totally different concept of “testing”, namely “integration testing“.
While unit tests focus on individual “unit“s of code, integration tests control how all the individual units work as a whole. Integration tests are not replacements for unit tests; they complement one another.
To see how integration test can be used to complement your unit tests, and to read up further on integration testing, you may want to check out projects like Selenium, or WatiN.
Any Unit Testing is Better than None
Refactoring without tests leads to bugs. Rather than avoiding unit tests, because they are badly written, working on to improve these test should be the approach to follow.
Writing unit tests puts you into a completely different state of mind:
Instead of writing code that “just works”:
- You start thinking of writing code that’s not dependent to other modules,
- You start thinking of fail-case scenarios that the code won’t run as expected,
- You start thinking about code as a contract,
- You start visualizing your unit as a black box with definite input/output relationships,
- You start thinking in “should“s, instead of “could“s,
- You constantly and unconsciously as yourself “how do I test this one line of code”.
But When You Have a Hammer…
… everything looks like a nail, doesn’t it
?
This may surprise you but unit testing is not for finding bugs. If you’re trying to find bugs, you had better test the integrity of the application by running the whole application together and manually testing it for bugs.
There are paradigms for different cases:
- If you want to find out things which don’t work as you want them to be (i.e. bugs), do manual testing,
- If you want to detect things that used to work which do not work as expected anymore (i.e. regressions), do automated integration tests,
- If you want to design robust and reliable software components with solid input/output relationships, do unit testing.
So, What Makes a Good Unit Test?
A good unit test suite is invaluable. It makes it easier to refactor and expand your code while keeping an eye on each individual component’s behavior.
I will go as far as to say that a suite of well-crafted unit tests is a means to document your code.
Here are the common characteristics of a good unit test suite:
- Each test is orthogonal to one another:
That is to say, each test should be independent from one another. changing the behavior of a test should not affect other tests. And changing the order of the tests in a suite, should not change the outcome of each individual test. - Do not make redundant assertions:
Do not assert anything that is also covered by another test. Keep one and only one logical assertion for each test, because if you have more than one logical assertion per test, a failing test’s reason of failure can become ambiguous. - Try mock objects, whenever you can.
- Have a clear and consistent naming scheme:
Do not use generic names for your unit tests such as “tests page login”.I generally use the following pattern for naming my unit tests:
“{some action} SHOULD {some outcome} {some condition}”,
as in
“Page Login should return false if email is invalid.”
Inversion of Control / Dependency Injection
Each unit test should contain knowledge about the behavior of a single unit of code that it’s testing.
If the unit’s behavior changes so should the corresponding unit test. Though the test should not contain any assumption at all about other parts of your code base.
You should be able to test your modules independently. Changes to one unit should not generate a chain reaction of failures in other units. Inversion of Control is an excellent design pattern adhering to this philosophy.
Conclusion
Unit tests are the design specs of the module’s behavior, they are not an observation of everything the code does. Unit tests query how the module does its job, rather than what it does.
In a nutshell, carefully thinking about your unit tests before coding will help you focus and see things you’ve never seen before. Your code will not look the same again
… What’s Next?
This article was the “talking the talk” part of unit testing. In the upcoming article we will “walk the walk” and create a JavaScript unit testing suite from the ground up
.
Until then, feel free to share your comments and suggestions
.
Do you favor unit tests?
What practices do you adhere when testing your code?
I’d love to hear them


Thanks for a good explanation of different kinds of testing. I think this is a nice introduction to unit testing in general, rather than just JavaScript unit testing. I’m looking forward to the next part
@Halil, You are right, this is particularly an introduction to unit testing in general
.
You need to build a solid foundation before you teach to use a paradigm properly. That’s one of the building blocks of pedagogy.
The same principle also aplies to self-learning, as well as teaching/mentoring:
The list may go on on an, though I’m sure you get the point
.
looking forward to the coming articles, seems that an enlightening series is on the way..
@Erdem, I’ve just finished the draft of the second part of the series
Stay connected
Actually you can have a look at the code of “what’s next” at https://github.com/v0lkan/o2.js/blob/master/tests/demo.html
Cheers
Hey very cool website!! Guy .. Beautiful .. Superb .. I’ll bookmark your blog and take the feeds additionally…I’m satisfied to search out a lot of useful information right here within the post, we’d like work out more strategies in this regard, thank you for sharing.
Thank you David! I try to write about the mysteries and intricacies of the JavaScript world as much as I can. I am glad that it’s being useful.
In deed I’m drafting yet another blog post right now.
Cheers.
[...] then I came across this another javascript framework named o2. The owner of this project also has blog posts about how to write unit tests in javascript and he goes on to explain how u can manage a queue of [...]