stackademic

The leading education platform for anyone with an interest in software development.

Testing Fundamentals

Why automated tests exist and the core vocabulary every developer needs

Overview

Automated tests are code that checks whether your other code behaves as expected. They catch bugs before users do, document how a system is meant to work, and let you change code with confidence. Most test suites follow the same shape: set up some inputs, run the code, and assert the result matches what you expected.

Syntax / Usage

A test file describes behavior with a name and verifies it with an assertion. The common pattern is Arrange–Act–Assert: prepare inputs, call the code, then check the outcome.

// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = { sum };

// sum.test.js
const { sum } = require("./sum");

describe("sum", () => {
  test("adds two positive numbers", () => {
    // Arrange
    const a = 2;
    const b = 3;
    // Act
    const result = sum(a, b);
    // Assert
    expect(result).toBe(5);
  });
});

Run tests with npx jest. A green run means every assertion passed.

Examples

A test that checks a specific expected value:

test("adds negative numbers", () => {
  expect(sum(-4, -6)).toBe(-10);
});

A test that verifies an error is thrown for bad input:

function divide(a, b) {
  if (b === 0) throw new Error("Cannot divide by zero");
  return a / b;
}

test("throws when dividing by zero", () => {
  expect(() => divide(10, 0)).toThrow("Cannot divide by zero");
});

Common Mistakes

  • Writing tests that assert nothing, so they always pass no matter what
  • Testing implementation details instead of observable behavior, making tests brittle
  • Depending on test order, where one test only passes because another ran first
  • Using vague test names like "works" that don't describe the expected behavior
  • Skipping the "arrange" step and reusing shared mutable state between tests

See Also

testing-unit-tests testing-integration-tests testing-code-coverage