Your Front End Code Needs To Be Unit Tested

Anuradha Kumari
JavaScript in Plain English
6 min readDec 1, 2020

--

your frontend code needs to be unit tested — by Anuradha Kumari

Front End testing can be done in multiple ways, like unit testing, integration testing, system testing, and acceptance testing. Today, we are going to explore the importance of unit testing and the tips to test our frontend code.

Introduction

In my 7+ years of frontend development experience, I have met very few people who are willing to write unit test cases for their code. It is usually optional; something developers take up as a tech task if they have extra time. A lot of people think it a waste of time, effort, and resources.

But, if anything, unit testing is an investment in the future. If done properly, unit tests can save a lot of time, effort, and resources in the long run.

Hence I feel that it’s the need of the hour to talk more and more about it and give importance to test-driven development as much as the business logic.

What Is Unit Testing?

Unit testing means testing individual units of the source code and verifying if that particular unit works as expected.

Here, the unit can be the smallest part of the application/module that can be tested in isolation.

It can be:

  • a class in object-oriented programming,
  • a function in procedural programming,
  • a component in React, Angular, Vue, Svelte, and so on.

The main intent of unit testing is to verify the logic of our code — the code should work well for all possible scenarios. If it does, then we can be sure that the application will not break.

Piece of puzzle with text unit testing written on it
Image credits: pcloudy.com

Benefits of Unit Testing

Makes the process more agile

As the application evolves and additional features are added to it, it might require revisiting earlier designs and code. Unit tests can detect code-breaking changes in design contracts, allowing these issues to be found early and thus resolved quicker.

Helps in the safer refactoring and easier debugging

When we refactor code, we only change the code structure and not the end result. The refactored code should work the same way as before. So, if we have proper unit tests in place, any defect introduced to the code refactoring can be easily detected by the test cases. We can also easily detect where to debug if any of the test cases fail. This also makes the debugging process easier.

Helps us create a robust, understandable codebase

It is critical to write logical test cases so that if anyone makes any design change in the component/function, the unit test should fail. That’s how any developer, new to that codebase, can understand what was the original purpose of that code.

Helps with documentation

Good unit test cases serve as documentation for the future. When a codebase is well-documented and properly unit-tested, then it is easy to maintain.

Now that we know how unit tests help the development cycle, let’s look at some tips on testing the frontend code.

Deciding What Frontend Code to Unit Test

To be able to unit test our code efficiently, we should know what to test. If we look at assertion libraries, or the APIs provided to write unit test cases, we may feel overwhelmed by the possibilities of test cases that can be written for a piece of code.

The more your tests resemble the way your software is used, the more confidence they can give you — tweet by Kent C. Dodds

We will explore some important tips through basic JavaScript examples and see what assertions can be written. The unit test cases are written in Jest.

Let’s say we have an input box that should accept only alphanumeric values from a user. To validate the user’s input, I have created a validator function named ‘alphanumericValidator.’ It takes in a string and returns a boolean value (true for valid input, false for invalid input). Here’s the code:

export function alphanumericValidator (input) {    
if (!input) {
return false;
}
var alphanumericExp = /^[0-9a-z]+$/;
if (input.match(alphanumericExp)) {
return true;
} else {
return false;
}
}

The essential scenarios that should be covered through testing are:

The business logic implemented should be tested properly

The unit tests should test what the code is supposed to do. For example, we will check if the validator is working properly with the below assertions:

// test if it returns true for valid input//TEST 1: for only alphabets expect(alphanumericValidator('onlyAlphabets')).toBe(true);// TEST 2: for only numbers expect(alphanumericValidator('123')).toBe(true);// TEST 3: for both numeric and alphabets together
expect(alphanumericValidator('alphabets123')).toBe(true);

These tests ensure that our frontend code is working as expected. The validator indeed validates correctly for the alphanumeric values and hence, it’s working properly and adhering to the business logic.

All the conditions and branches present in the code should be tested

All the if and else switch cases in the code should be unit-tested to verify if the code is working as expected for all possible real-time scenarios.

// TEST 4: testing the else path for invalid inputexpect(alphanumericValidator('alpha123@@@@@@')).toBe(false);// TEST 5: for special characters inputexpect(alphanumericValidator('#./')).toBe(false);

These tests make sure that our frontend code does not allow users to input any unacceptable value, like special characters. This is an extension of the first rule and helps us prevent bugs that might occur due to incorrect values sent in by the user by mistake.

Testing the unexpected scenarios or the negative use case

We should test the error scenarios by trying to break the code and verify through test cases that the code does not break at the corner cases or unexpected input scenarios, like null/undefined values. This is especially important when we have optional parameters.

// TEST 6, 7: for null/undefined input valuesexpect(alphanumericValidator(null)).toBe(false);
expect(alphanumericValidator(undefined)).toBe(false);
// TEST 8, 9: for empty strings or no input valuesexpect(alphanumericValidator('')).toBe(false);
expect(alphanumericValidator()).toBe(false);

These tests make our frontend code robust and avoid breaking of the application and websites due to unexpected inputs entered by the user.

Skippable Scenarios

While there are some scenarios that are essential to test for our code to be robust, there are some other scenarios that qualify as not-so-essential to test through unit test cases.

Let’s explore some of such use cases:

  1. Testing for static values, constants, enumerations, etc.

Such test cases do not help in any substantial way, rather than just increasing the code coverage percentage (which has not much to do with code quality). Example:

expect(1).toBe(1);

2. Testing for the functionalities of external dependencies or libraries

The term ‘unit testing’ means to test the unit and hence, testing the actual functionality of any dependency used in that unit does not add any value to the unit testing process. This is because the functionality of that external dependency will already have been verified and tested through separate test cases written while unit testing that unit.

Tools for unit testing

Since there are multiple programming languages in which we can code, there are multiple tools, libraries, and frameworks available for unit testing that code. PFB some of the tools for unit testing the frontend code written using either Vanilla JavaScript or JavaScript libraries/frameworks:

Conclusion

There have been many times where I have thanked my past self for writing that piece of a test case which saved me from making a huge mistake and preventing an otherwise almost certain production bug.

Unit tests should not be seen as an overhead or burden, instead, we should embrace them as a daily practice and a healthy coding habit.

Image of Ned stark with the quotation — One does not simply refactor legacy code without unit tests.
image credits: meme generator

Stay tuned and catch you in the next article !! Any feedback is highly appreciable.

Thanks for reading, have a great day!!

--

--

Web Developer, Accessibility Advocate, Google Developers Expert, Microsoft MVP, anuradhakumari.com ‘Choose RIGHT over easy, always!’