What’s testing and why should we do it?

Part 1 of 5 in our Testing like a Pro in JavaScript series.
Written by Alex Jover Morales

In the very first article in this 5 part series about testing in JavaScript, we’re going to look at what testing really is and why we should do it.

Testing, in software engineering, is the process to evaluate that all parts of an application behave as expected.

The tests perform verifications on the software by checking that the received output matches the specifications, given different inputs. Each of those verifications are called test cases. In an agile workflow, each user story should have a set of test cases. A simple example:

US-01: Create a currency input component

Test cases:
– TC-01: It should accept only numbers
1. Type the number “2”. Expected: it should be ok
2. Type the character “a”. Expected: it should display a “Only numbers allowed” message
– TC-02: It cannot be empty

The test cases verify the requirements and specifications of a specific feature. They could provide some details or steps to try to reproduce it as well.

Chances are, if you’re reading this article, you know what testing and TDD is already, and if you’re new to testing you may have the question we all had:

Doesn’t testing take too much time?Do I need to test everything?

In this article we’ll talk about the pros and cons of testing, and also teach you to do your very first unit tests in JavaScript with Jest.

Why write tests?

Talking about the why about testing, it indeed provides some advantages:

  • Saves money: without proper testing, the amount of time and resources needed to maintain a product in the long term are much more than the invested on testing, not to mention the times something will break.
  • Provides code safety on teams: software is often build by teams. Different people modify the same piece of code over the time. Having tests makes that process safer, since no one can break something without knowing it. This is also true for your future self, it provides code safety when you come back in a year or two to make changes.
  • Helps to build a better architecture: when a piece of software is hard to test, usually is because it’s tightly coupled with other pieces or its functionality is too complex. Testing them will suggest you to apply decoupling, delegation and design patterns to keep the software as simple and testable as possible.
  • Increases code quality: Your product is less prone to breakage due to the fact that tests help you build a better architecture.
  • Makes refactoring easy and safe: building software is an iterative process. Requirements change over the time, thus the functionality. Having a good test coverage allows you to modify some code while checking that the tests still pass. If they don’t, you modify the code to adapt the the established output contract defined by the test.

I hope you’re convinced at this point of why testing is good for you, your application and your company.

Test Types

Tests fall into different types. Each test type has its own purpose and scope, and you must be aware of it. Every developer at some point writes a test which is testing something it shouldn’t.

We have three main types of tests:

Master Vue.js with Vue School

Top notch Vue.js courses and over 200 lessons for just $12 per month!

  • End to End (E2E): test the system as a whole, emulating an actual user environment. In web, they’re tests run in the browser, emulating mouse clicks and key strokes. In general, a test suite shouldn’t have too many of these, since they’re expensive to maintain and can get obsolete easily due to testing the system as a whole.
  • Integration: its purpose is to make sure that multiple dependant units work together and their interaction works as expected.
  • Unit tests: they test a specific functionality in isolation. They’re the easiest to create and maintain, that’s why most of a test suite are unit tests.

The pyramid describes the balance of the difference types of tests. The lower part are the fastest, easiest and most isolated tests, while the upper are more expensive, slowest and app-wide.

The integration layer can be separated even in more layers:

Although there is a bit of disagreement about how many types of tests are and their names, the most common ones are components and API tests. They’re just a specific type of integration tests. The component tests, in particular, are the ones we do on the front-end side when testing in Vue.js.

Static Analysis

Tests are not the only tool to provide code quality. In modern times of JavaScript, we also have static typing and linters. They both perform static analysis of your code to find inconsistencies, bad usage of the language, bad practices, data contracts and more.

Static typing makes your code safer in a per-contract bases. Tools like TypeScript or Flow allow you to define variables, parameters and returned values types. They assure your classes, functions and methods have a specific structure, and that the rest of your code are asserting it. Lots of companies that adopted static-typing started to catch several errors straight away, for free.

Let’s compare the typed version and the non-typed version of a sum function:

// Non-typed
function sum(a, b) {
    return a + b;
}

// Typed
function sum(a: number, b: number) : number {
    return a + b;
}

The non-typed version doesn’t prevent us to call it with strings, which returns a string concatenation. For example, calling sum('1', '2') returns '12'. However, if we’re using static typing, we get an error such as Argument of type '"1"' is not assignable to parameter of type 'number', preventing us at compile time from making a mistake.

Linters are software that analyse and review different aspects of the code on compile time. JavaScript, without the benefits of a compiler, is prone to errors compared to other languages. ESLint is the de-facto linter in JavaScript, while TSLint in the TypeScript community.

A linter tries to fill the gap by providing rules that check syntax errors, code styling and problematic patterns. As a result it reduces bugs and increases the quality and consistency of your code.

As an example, if you use the [no-var](https://eslint.org/docs/rules/no-var) rule in ESLint and write the following code:

var greet = 'Hallow, Kitty';

You’ll get the error Unexpected var, use let or const instead (no-var).

In the pyramid, static analysis is even more specific and quicker to check (almost real time) than unit tests, making it the base of the pyramid:

Master Vue.js with Vue School

Top notch Vue.js courses and over 200 lessons for just $12 per month!


Article written by Alex Jover Morales

Passionate web developer. Author of Test Vue.js components with Jest on Leanpub. I co-organize Alicante Frontend. Interested in web performance, PWA, the human side of code and wellness. Cat lover, sports practitioner and good friend of his friends. His bike goes with him.