Chapter 4. Adding Tests and the Importance of 100% Code Coverage
In this chapter, we are going to explore the topic of testing in Node and hapi. We will look at writing a simple test using hapi's test runner lab, testing hapi applications, techniques to make testing easier, and finally, achieving the all-important 100% code coverage.
Testing is often a contentious issue when it comes to development. There are different attitudes towards its importance and relevance in the development cycle. Some developers believe in a Test-driven Development model, where tests should be written first. Others write tests while developing or wait till development is complete, then try and reach 100% code coverage with their tests. Unfortunately, in most cases, many don't bother with any at all, usually with what I believe to be as the naive view that "there isn't enough time to write tests".
Note
Code coverage is the percentage of lines of application code that are executed by a testing suite.
Most of my career...
Why is the importance of testing overlooked?
In my experience, most development comes from two motivations: employment or recreation. There are others such as creating open source software (like hapi), research, and the like, but most of them fall under the aforementioned two categories. The motivation behind both categories is usually result-focused; when the motivation is employment, we aim to generate a monetary value from the code that we write. In case it is recreational, we are often exploring a new technology and just want to build something for a demo or to learn the inner workings of a new framework or library. It's easy to see how writing tests doesn't fit into either category.
In case of development for employment, tests aren't a sellable feature of software and are expensive. They take a lot of time and money to design, write, maintain, run, and keep up-to-date with best practices. Often, the size of a testing codebase will be larger than that of the codebase it is testing. The...
The benefits and importance of testing code
I mentioned the concept of technical debt in the previous chapter, which, as a reminder, is the building up of work that must be done before a particular job is complete, making changes much harder to implement in the future. A codebase without tests is a clear indication of a technical debt. Let's explore this statement in more detail.
Even very simple applications will generally comprise of the following:
Features, which the end user interacts with
Shared services such as authentication and authorization that features interact with
These will all generally depend on some direct persistent storage, or API. And finally, for implementing most of these features and services, we will use libraries, frameworks, and modules, regardless of language. So even for simpler applications, we have arrived at a few dependencies to manage already, where a breaking change in one could possibly break everything up in the chain.
So let's take a common use case in which...
Introducing hapi's testing utilities
The test runner in the hapi ecosystem is called lab
. If you're not familiar with test runners, they are a Command-line Interface (CLI) tool for running your testing suite. It is inspired by a similar test tool called mocha
, and in fact, initially began as a fork of the mocha
codebase. But as hapi's needs diverged from the original focus of mocha
, lab
was born.
code
is the assertion library commonly used in the hapi ecosystem. An assertion library forms the part of a test that performs the actual checks to judge whether a test case has passed or not, for example, checking if the value of a variable is true after an action has been taken.
Let's look at our first test script, then we can take a deeper look at lab
and code
, how they function under the hood, and some differences they have with other commonly-used libraries such as mocha
and chai
.
You can install lab
and code
the same way as any other module on npm:
Testing hapi applications with lab
As I mentioned earlier, testing is considered paramount in the hapi ecosystem, with every module in the ecosystem having to maintain 100% code coverage at all times, as with all module dependencies.
Fortunately, hapi provides us with some tools to make the testing of hapi apps much easier through a module called shot
, which simulates network requests to a hapi server. Taking our first example of the hello world server given in Chapter 1, Introducing hapi.js, let's write a simple test for it:
In this chapter, we've looked at testing in Node and hapi, and how testing as well as code coverage are paramount in the hapi ecosystem. We've seen justification for their needs in application development, and how they can make us a more productive developer.
We've also introduced the test runner and code assertion libraries lab and code in the ecosystem and justified their use. You've learnt how to use them for writing simple tests, and how to use the tools provided in lab and hapi to test hapi applications.
You've also learned of some of the extra features baked into lab such as code coverage and linting. We looked at testing the code coverage of an application and getting it to 100%, and explained how the hapi ecosystem applies the hapi style guide to all the modules using the linting integration inlab
.
As always, all code samples seen here as well as some extra material can be found online in the repository available at https://github.com/johnbrett/Getting-Started-with-hapi.js.
However...