Why unit testing is important?

Imagine working till 9pm at the office, trying to fix a bug that was raised earlier that day. After countless trials, errors and keyboard smashes, you finally manage to find a solution. You commit the changes, pat yourself on the back and call it a day. As you walk into the office the next morning, your team member tells you that a regression occurred caused by a code change last night. “Darn it” you mutter as you make your way back to your desk.

How can a simple code change cause the entire codebase to crash and result in a regression? The answer is lack of testing.

Unit testing pays future dividends in terms of code reliability and extendability, however developers don’t always understand why the additional effort is beneficial. There’s a common misconception among developers that unit testing is unnecessary effort, so let’s dive into what is unit testing and why you should consider it part of your software development cycle.

What exactly are unit tests?

Unit testing is an efficient way to determine if your code is behaving as expected. Simply put, unit tests isolate and exercise modular pieces of your codebase. A common misconception of unit tests is that they are used to find bugs. In reality, it’s a specification for the anticipated behaviours of the code being tested. Let’s consider the MessageMedia Messaging API as an example. We know the Messages API capable of sending messages, receiving messages, checking delivery reports and other powerful messaging-related functions. A possible unit test for the API could comprise of checking whether the API responds with a 200 when a successful POST request is made. Another unit test might check and see if the API responds with a 400 when an incorrect POST request is made. Below is an example of a unit taken from our Lookups Node.js SDK. This unit tests lookups the carrier and type of the specified number and checks if it matches with the expected values.

it("should testLookupAPhoneNumber response", function testLookupAPhoneNumberTest(done) {
  let phoneNumber = '+61491570156';
  let options = 'carrier, type';

  controller.getLookupAPhoneNumber(phoneNumber, options, function callback(error, response, context) {
    assert.equal(200, context.response.statusCode);
    let headers = [];
    headers['Content-Type'] = null;
    assert.isTrue(TestHelper.areHeadersProperSubsetOf(headers, context.response.headers, true));
    assert.isNotNull(response);
    assert.equal('{"carrier":{"name":"AU Landline Carrier"},"country_code":"AU","phone_number":"+61491570156"}', context.response.body);
    done();
  });
});

Why do you need unit tests?

To explain this, let’s go back to the scenario previously mentioned. The breaking change occurred after the bug “fix” was made. If a change is made to a piece of code, then you are changing its definition and the expected behaviour. Unit tests act as the definition so each time you make a change it ensures the code behaves as expected. In addition to this, you understand how your code works in different scenarios and as a result, you gain more confidence in your code. Over time, as your code grows and becomes complex, it can be difficult to pinpoint errors. Your unit tests will act as a guide in those situations and will reduce the time taken to find the bug. As a developer, you can easily get carried away creating a new feature and over complicate the code. As it is considered good practice to write the bare minimum for the feature, writing unit tests before coding is the quickest and most reliable way of accomplishing this.

When should I start unit testing?

This is a very common question for anyone who is getting started with unit testing. Unit tests should be written alongside the code. Ideally, it should be before you start writing code. There’s an approach that talks about writing unit tests before your code, called Test Driven Development or more commonly known as TDD but that’s a discussion for a separate blog post.

It doesn’t really matter which order the tests are written, as long as the tests are done before the implementation of some functionality is considered “complete”. In the Agile world, this means finishing the unit tests during your sprint. Leave the unit testing implementation for later and you’re likely to fall into the “I’ll do it later” trap.

Final Thoughts

Even though there are many other types of tests, unit tests are the most basic kind which focuses on validating individual parts of a complex codebase. They can be a nuisance to write, especially if you’re just starting off but they pay dividends in the future in terms of code reliability and extendibility. Consider this popular software testing quote – “All code is guilty, until proven innocent.”


Continue reading...

Managing API documentation over multiple teams
Bec Martin
September 12, 2019
Your first Django project
Natalie Byrgiotis
July 08, 2019