Developers should love the security of unit tests. Nobody loves writing unit tests, but the peace of mind they bring can easily be worth the extra work.
Unit tests check blocks of code to ensure that they all run as expected. This is very common for traditional software development and now very common in web development too.
But how exactly does JavaScript fit into the unit testing process? In this post I’d like to explain the basics of unit testing, how it operates with JavaScript, and the best resources you can use to improve your workflow.
What Is Unit Testing?
A unit test runs some code over a segment of your program checking the input and output. These tests allow developers to check individual areas of a program to see where(and why) errors occur.
This comes with an inherent understanding of what you’re trying to test for and how the code should function. Checking for bugs and errors can only be useful when you know exactly what you’re looking for.
I found this blog post incredibly useful in regards to unit testing. There’s a lot to be said about preparing and documenting your work before going into it.
In the world of JavaScript things can get a little trickier because it runs on the frontend of a webpage. The easiest way to handle this is with separate JS libraries.
But how do you actually write unit tests and get some value out of them? The answer is different based on your code, so a C++ dev has a different methodology than a JavaScript dev.
Let’s go a bit deeper into unit testing for JS and see how this can be accomplished.
Frontend JS Testing
There’s no need to unit test for HTML/CSS because they’re not function-based languages. JavaScript is true scripting and with new resources like Node.js and TypeScript it’s becoming much more powerful.
Simple JS unit testing will take a function, monitor output and return its behavior. Smashing Magazine has a great example which tests a calendar date output function based on a specific type of input.
Not every JS project will need a unit test. But many developers prefer to be safe rather than sorry, and it’s always good to double-check work.
Every unit test is made to check against an individual unit in JavaScript, which typically breaks down to a function or library. The goal is to check every aspect of the function to make sure it all works properly for all cases.
A frequent topic of debate is between TDD and BDD for unit testing. Test-driven development(TDD) is basically the same as behavior-driven development(BDD) but with different terminology and approaches.
The biggest difference is that TDD follows a test-based implementation whereas BDD looks at behavior. This post has a great example explaining that BDD defines situations to help consider user behaviors.
So instead of laying out functions solely with logic, you’re thinking about how a user might send input and how that input might be passed to JavaScript(like unescaped HTML code). The TDD method takes this as raw data whereas the BDD method looks at behaviors first, then data.
They can honestly be considered the same but with different approaches to the same problem. I wanted to mention this terminology more as an introduction, but try not to get caught up in this too much.
Unit testing takes practice and the more tests you write the more you’ll understand. When first starting just focus on writing a test without worrying so much about perfect best practices.
Techniques & Strategies
Once you know what you’re testing you’ll want to get to work writing a test. But what exactly should you test for?
The most common scenario is one of input and user actions. Let’s say a user logs in and wants to set a cookie. Cookie setting is a particular behavior that should be tested based on multiple outcomes(failure and success of login).
Every test output should contain useful information to help you locate problem areas. Each failure report should have a few different properties which are outlined in this post:
- What feature/issue are you testing?
- What was the output after running the test?
- What’s the expected output for a successful test?
With this information you can check against every unit test and determine which part of the chain is failing.
Let’s say the login cookie doesn’t set when the user logs in, but it does set when the login fails. This is likely an issue with logic statements in the function and may give you some idea of where to look.
Other common unit tests including code linting and basic output response types. If a function gives you the wrong output, you want to know why and where it’s coming from.
Whenever writing a new test always try to keep your code very simple and to the point. The best way to stay simple is to have a clear idea in mind of what you’re checking and what type of output you’re expecting.
If you’re looking for more resources please check out these related posts.
- Writing Testable JavaScript
- JavaScript Testing: Unit vs Functional vs Integration Tests
- Setting up Unit Testing with Mocha and Chai
- Unit Testing Best Practices in AngularJS
Best JS Testing Tools
Unless you truly love writing vanilla JS then you should be working with JS libraries. The best ones will speed up your workflow and they’ll provide error-free libraries for testing your potentially error-laden code.
Jasmine.js
There’s no denying that Jasmine is one of the most popular JS-based unit testing libraries on the web. It’s completely free, open source, and frequently updated with new features.
Their documentation is stellar with beginner guides and plenty of code snippets. For example, you can test Ajax calls with Jasmine’s sample code without much thinking at all.
As of this writing the latest version of Jasmine is v2.4 with plenty of support. If you’re looking for a free tutorial I’d recommend this Tuts+ article to get you started.
QUnit
One of the safer choices out there is QUnit. This JavaScript unit testing framework was created by the jQuery team and it’s used on all of their projects(including jQuery UI and jQuery Mobile).
The site even has a writeup covering unit testing for beginners by teaching with the QUnit documentation. If you’re not sure where to start and have no clue about unit testing then pick up QUnit and follow their guide. By the end I guarantee you’ll have a much better understanding of how to write tests, why you’d want to, and the importance of a library such as QUnit.
Mocha.js
Many hands-on developers prefer the flexibility of Mocha.js because it allows you to write your own custom testing libraries from scratch. It’s easy to create modular unit tests by following Mocha’s guidelinesaEUR”and best of all the codes can be reused in other projects.
By default Mocha is a testing library which can work with other libraries like Chai.js for assertion testing. Chai allows for more than basic true/false test results and enhances the flexibility you already get with Mocha.
This is one of the best libraries you could choose to get started. It handles all the asynchronous methods and runs on Node.js like so many other modern JS libs.
Intern
One other choice I’d like to list isn’t exactly a framework, but rather a stack of options for JS testing. Intern is completely free and hosted as open source on GitHub. It’s labeled as “software testing for humans” and it’s a really cool platform.
Tests can be run in the browser or run in a custom Intern test runner. It can run tests on 3rd party frameworks like BrowserStack and supports every possible JS framework you could imagine.
The biggest downside is that it can be complicated for a complete beginner. But keep Intern in mind if you’re ever up for a challenge because it can save time connecting many different tools in your workflow.
There are way too many options to list here so it’s really up to you. Honestly you can’t go wrong either way, even if you want to roll your own library from scratch!
But if you’re looking for more handy testing tools I highly recommend these alternate(and free) solutions.
- Cucumber.js
- Casper.js
- AVA
- Vows.js
- Karma
The best way to understand unit testing is to simply try it on your next project. Not everyone has a need to write unit tests, so these principles may not apply to smaller personal projects.
But if you work in a team or if you’re planning to launch a much larger project then it’s good to build the habit of unit testing your code. I certainly hope this guide can get you started and offer the best resources to continue your journey of JS unit testing.
One Response