Simple Testing Definitions for Front-End Development

Simple Testing Definitions for Front-End Development

by Matt Leong


In the world of web app development, ensuring the reliability of your application is paramount. This is where different testing methods come into play: unit testing, integration testing, and end-to-end (E2E) testing. Each serves a unique purpose and, when used appropriately, contributes significantly to the stability of your application.

Unit Testing: The Microscope

Unit tests are the first line of defense. They help in verifying the smallest parts of your code, specifically individual functions.

Example with Jest

Imagine you have a simple function add:

function add(a, b) {
  return a + b;
}

A unit test using Jest might look like this:

import { add } from './math';

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

This test checks if add works as expected for a given set of inputs.

Integration Testing: Connecting the Dots

Integration testing is all about ensuring that different components work well together. Typically, this is done in a controlled and mocked environment.

Example with React Testing Library

Consider a React component LoginButton which calls a function login on click:

import React from 'react';

function LoginButton({ login }) {
  return <button onClick={login}>Log In</button>;
}

An integration test with React Testing Library could look like this:

import { render, fireEvent } from '@testing-library/react';
import LoginButton from './LoginButton';

it('calls login on button click', () => {
  const mockLogin = jest.fn();
  const { getByText } = render(<LoginButton login={mockLogin} />);

  fireEvent.click(getByText('Log In'));
  expect(mockLogin).toHaveBeenCalled();
});

This test checks if the LoginButton correctly calls the login function when clicked.

End-to-End (E2E) Testing: The Full Dress Rehearsal

E2E testing simulates real user scenarios to ensure the entire application functions as expected in a production-like environment.

Example with Cypress

For a web app with a login page, an Cypress E2E test might look like this:

describe('Login Test', () => {
  it('successfully logs in', () => {
    cy.visit('/login');
    cy.get('input[name=username]').type('user');
    cy.get('input[name=password]').type('password');
    cy.get('button[type=submit]').click();
    cy.url().should('include', '/dashboard');
  });
});

This test automates a browser, fills out the login form, submits it, and checks if the user is redirected to the dashboard.

Summary

In web app development, a balanced approach to testing - unit, integration, and E2E - is essential. Unit tests keep the basics solid, integration tests ensure that the parts play well together, and E2E tests confirm the app’s readiness for the real world. Combined, they contribute to the development of robust, user-friendly applications.

What is that balance, you ask? Well there are a few schools of thought. Some like Kent C. Dodds say you should be writing mostly integration tests, while others say tests aren’t important and kills productivity.

Personally, I believe tests to be important, particularly for enterprise level applications when you potentially have multiple teams working within the same codebase. In those cases, testing ensures that contributions from other teams have an extra level of confidence. Additionally, I am not a fan of setting a goal for 100% testing coverage. It’s best to just focus on testing for most critical parts of your application, rather than spending .