View on GitHub

Matt's homepage

Bookmark this to keep an eye on new things I am learning.

Unit Testing

Unit testing involves testing units of code so that functionality can be confirmed within the application.

A unit testing framework offers both immediate and long-range benefits. In the short term, unit tests facilitate a quicker development process by allowing for automated testing. Over the long term, unit testing yields savings in labour costs because less debugging is needed for code changes or package updates.

Unit tests can be automated into the build pipeline so that they are run on checkin or push. This yields immediate feedback to the developer so that issues are found and fixed early.

Return Home

Jest

Jest is a JavaScript Testing Framework with a focus on simplicity. It works with projects using: Babel, TypeScript, Node, React, Angular, Vue and more!

^ back to top ^

Install Jest

With these commands from your project folder:

npm i jest --save-dev
npm i @types/jest --save-dev

^ back to top ^

Setup

Create a folder called tests in the root of your project. This will be where you put all the tests for your code. Under this, I like to mimic the folder structure for what is in src. This way it is easy to map tests to code.

in your package.json file, under the scripts section, add en entry for test.

    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"

In your .gitignore file, add a line to exclude the test coverage folder. (something created when you run tests)

/coverage

^ back to top ^

Creating test files

Lets say you have a file called src/calc.mjs, which is a utility file to give basic calculator functions to your code. (add, subtract, multiply, and divide)

calc.mjs

Create a calc.test.mjs file under tests folder.

Each *.test.mjs file is considered a test suite which can have many included tests.

On the first line of this file, import your calc.mjs file that you will be testing.

import { add, mult, sub, div } from '/src/calc.mjs';

^ back to top ^

Running tests

Now that you have a test script set up in package.json, you can run the test suites by running this command.

npm run test

Right now, you won’t see much as you haven’t written any tests yet. But you will see a display that shows you test coverage. Coverage shows you a report for what code you have and do not have test cases written for.

You should aim for 100% coverage

File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 75 75 75 75  
calc.mjs 75 75 75 75 57-60

More detailed coverage reports are created in the /coverage folder.

^ back to top ^

Creating tests

Discrete tests

Create tests use expect and matches to test values in different ways.

Calls the add function with two parameters and expects the return value toBe a specific result.

test('adds two positive numbers', () => {
  expect(add(2, 3)).toBe(5);
});

^ back to top ^

Grouping output

Better yet, you can group tests under a describe tag, so you logical groupings in the output.

describe('Add function', () => {
  test('adds two positive numbers', () => {
    expect(add(2, 3)).toBe(5);
  });

  test('adds two negative numbers', () => {
    expect(add(-2, -3)).toBe(-5);
  });
});

Yields this in the output.

 PASS  tests/calc.test.mjs
  Add function                                                                           
    √ adds two positive numbers (1 ms)                                                                              
    √ adds two negative numbers (1 ms)

^ back to top ^

Matchers

Jest uses matchers to test in different ways. There is an expectation (expect) of something to match something.

toBe(n)

Matchs on exact equality

expect(2+2).toBe(4);

Can also use expect.not.toBe()

^ back to top ^

toEqual

Matches by value (including implicit values)

expect(1).toEqual(true);

Can also use expect.not.toEqual()

^ back to top ^

Truthiness

^ back to top ^

Numbers

^ back to top ^

toMatch (or not.toMatch)

Checks strings again regular expressions

expect('Hello world').toMatch('/world/');

^ back to top ^

Arrays and iterables

expect(shoppingList).toContain('milk');

^ back to top ^

Exceptions

To test for expected errors.

expect(() => aFunction().toThrow());
expect(() => aFunction().toThrow('/specific/))
expect(() => aFunction().toThrow('A specific error'))

^ back to top ^