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:
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 a new version of one of your dependencies is released. That could be a new hapi version, a smaller library, your persistent storage engine, MySQL, MongoDB, or even an operating system or language version. SemVer, as mentioned in the first chapter, attempts to mitigate this somewhat, but you are taking someone at their word that they have adhered to this correctly, and SemVer is not used everywhere. So, in the case of a breaking change, the following questions arise:
Without a good automated test suite, these have to be answered by manual testing, which is a huge waste of developer time. Development progress stops here each time these tasks have to be done, which means that these type of tasks are rarely done, building further technical debt. Apart from that, humans have been proven to be poor at repetitive tasks, prone to error, and I know I personally don't enjoy manual testing, which makes me poor at it. I view repetitive manual testing as time wasted, as these questions could easily be answered by running a test suite against the new dependency so that developer time could be spent on something more productive.
Now let's look at a worse and still common example; a security exploit has been identified in one of your dependencies. As mentioned previously, if it's not easy to update, you won't do it often so you could be on an outdated version that won't receive this security update. Now you have to jump multiple versions at once, scrambling to test them manually. This usually means many quick fixes, which often just cause more bugs. In my experience, code changes under pressure are what deteriorate the structure and readability in a codebase, leading to a greater number of bugs, and are a clear sign of poor planning.
A good development team, instead of looking at what is currently available, will look ahead to what is in beta, and will know ahead of time if they expect to run into issues. The questions asked will be: will our application break in the next version of Chrome? The next version of Node? hapi does this by running the full test suite against future versions of Node, alerting the Node community of how planned changes would impact hapi and the Node community as a whole. This is what we should all aim to do as developers.
A good test suite has even bigger advantages when working in a team, or when adding new developers to a team. Most development teams start out small and then grow, which means that all the knowledge of the initial development needs to be passed onto new developers joining the team. So, how do tests benefit here?
This is not an exhaustive list on the importance of benefits of writing tests for your code, but hopefully, it has convinced you of the importance of having a good testing suite. So now that we know why we need to write good tests, let's look at hapi's test runner lab and assertion library code, and how, along with some tools from hapi, they make writing tests a much easier and a more enjoyable experience.
18.118.93.64