0%

jest-from-scratch

In this post, I will show you how to set up a Jest project from scratch. We won’t use any front-end frameworks like React, Angular, or Vue, just a simple vanilla JavaScript project.

CommonJs

Step 1: Create a new project

Run the following command to init a new project directory, it will simply create a package.json file in the current directory.

1
npm init -y # with -y, you don't need to answer the questions

Step 2: Install Jest

Run the following command to install Jest as a dev dependency.

1
npm install --save-dev jest

Step 3: Create a javascript file

We’ll first focus on CommonJs, create a new file named sum.js in the root directory of your project, and add the following code:

1
2
3
4
function sum(a, b) {
return a + b;
}
module.exports = sum;

Step 4: Create a test file

Create a new file named sum.test.js in the root directory of your project, and add the following code:

1
2
3
4
5
const sum = require('./sum');

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

Step 5: Update package.json

Add the following line to the scripts property in the package.json file:

1
2
3
"scripts": {
"test": "jest"
}

Step 6: Run the test

Run the following command to run the test:

1
npm test

Run test with coverage

Run the following command to run the test with coverage:

1
npx jest -- --coverage

ESModule

To run Jest with ESModule, first rewrite your file and test file to use ESModule syntax.

1
2
3
4
// sum.js
export default function sum(a, b) {
return a + b;
}
1
2
3
4
5
6
// sum.test.js
import sum from './sum.js';

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

Run the test, you will got following error:

1
2
Jest encountered an unexpected token
SyntaxError: Cannot use import statement outside a module

This is because you are trying to use ESModule syntax in a CommonJs environment, to fix this, you can update your file name to sum.test.mjs or you need to add the following line to the package.json file:

1
2
3
4
"jest": {
"moduleFileExtensions": ["js", "mjs"],
"transform": {}
}

Then run the test again, it still not work, got the following error, it seems that Jest didn’t find any test file with the default pattern.

1
2
3
4
5
6
7
8
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In D:\personal\codes\jest
5 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 5 matches
testRegex: - 0 matches
Pattern: - 0 matches

Update jest config in package.json file to include mjs file extension in testMatch, see micromatch for detail matching rules. Note: this is not regex.

1
2
3
4
5
"jest": {
"testMatch": [
"**/?(*.)test.?js"
]
},

Then run the test again, got the previous error again

1
SyntaxError: Cannot use import statement outside a module

Then search jest official documentation, change jest command in package.json file to:

1
2
3
4
5
"scripts": {
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
},
}

Then run the test again, it works now.

Using config file

You can move the jest config in package.json to a separate file named jest.config.js, and update the package.json file to use the config file.

1
2
3
4
"scripts": {
"test": "jest --config jest.config.js"
"test-esm": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.config.js"
}

Then create a new file named jest.config.js in the root directory of your project, and add the following code:

1
2
3
4
5
module.exports = {
moduleFileExtensions: ['js', 'mjs'],
transform: {},
testMatch: ['**/?(*.)test.?js'],
};

Then run the test again, it works now.