Javascript Quality Control with Jest 🤹 and ESLint ✨
Working on a project with multiple people can be fun, but javascript is a very flexible language. As everyone has their own way of writing code, it’s not always easy to maintain high code quality standards.
With the help of Jest, ESLint and git-hooks we are able to automate some tasks to guard our code and make sure that our app never breaks again.
1 — Getting started with Jest 🤹
Before we start juggling let’s see why Jest is good for the task:
- It works out of the box
- Automatically finds tests
- Automatically mocks function dependencies
- It’s blazing fast 🔥
To get started we need to install Jest as one of our dev dependencies using npm:
npm install jest --save-dev
or using yarn
yarn add jest --dev
Jest works out of the box so place the tests in a __tests__
folder, or name the test files with .spec.js
or .test.js
extension.
Let’s add the test command in our package.json
// package.json{
"scripts": {
"test": "jest"
}
}
Now we can use npm test
or yarn test
from the terminal to run our unit tests.
How to watch the unit tests
When in development mode, we are likely to watch the tests running. This means we don’t need to rerun the process every time we make changes and our test
command will restart automatically.
We easily do that by executing Jest with the --watch
flag, our package.json
should look like this now:
// package.json{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
Configuring Jest to show your code coverage
Add the --coverage
flag to Jest for the test
command
// package.json{
"scripts": {
"test": "jest --coverage",
"test:watch": "jest --watch"
}
}
We want our command to fail in case we forget to test any code, to do so we will define every threshold to be 100% for: statements, branches, functions, lines.
// package.json{
"jest": {
"collectCoverageFrom": [
"*.js"
],
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"coverageThreshold": {
"global": {
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
}
}
Now when you run npm test
it will output the coverage results in the terminal (see below) and also create a folder called coverage
where we will find a full report.
Now my favourite part, if you open this file:
open coverage/lcov-report/index.html
You can interactively navigate through your repository and clearly see in your code any uncovered area.
NB. Update .gitignore
to exclude the coverage
output folder.
// .gitignorenode_modules
coverage
2 — Installing ESLint ✨
Linting code should be part of every developer daily workflow. Some of the benefits of linting your code include:
- Improved readability
- Finding syntax errors before execution
- Disallow unused and undeclared variables
- Solves the tab vs. spaces debate 😉
ESLint is the best tool of choice. It’s easy to configure and can be extended using plugins, so let’s install it locally using npm:
npm install eslint --save-dev
or using yarn
yarn add eslint --dev
How to configure ESLint
Cool, let’s create a basic configuration through a file called .eslintrc
, run:
touch .eslintrc
and add these lines:
// .eslintrc{
"env": {
"browser": true,
"es6": true,
"jest": true,
"node": true
},
"extends": [
"eslint:recommended"
]
}
No rules are enabled by default, therefore adding the "eslint:recommended"
property enables rules to report common problems. If you want to know what’s included, check the official list of available rules.
You are likely to write es6
nowadays, maybe some node
code too so, we configured "env"
to not validate code that might be specific to the browser, es6
, jest
or node
.
How to exclude files from linting
We also don’t want to lint any file produced with the coverage
report and we don’t want to validate anything inside node_modules
, so to exclude these folders we need to create a new file called .eslintignore
where we can add any PATH that we want to ignore:
// .eslintignorenode_modules
coverage
Now let’s add the lint
command in our package.json
// package.json{
"scripts": {
"lint": "eslint .",
"test": "jest --coverage",
"test:watch": "jest --watch"
}
}
We can now run npm run lint
or yarn lint
and validate our code with ease:
PRO TIP — What about running ESLint fix command on every file save?
3 — How to set up a git pre-hook ⬆️
Good software development involves running the tests frequently and making sure the code high quality standards are met. Adding a git-pre-push hook can help you to automate these tasks and avoid pushing some nasty code into your repo.
To easily do that we will be using husky 🐶 — a git-hook made easy library.
Let’s install husky using npm:
npm install husky --save-dev
or using yarn:
yarn add husky --dev
Then we simply need to write our prepush
hook in the package.json
, husky will automatically know that’s the command to run on git push
:
// package.json{
"scripts": {
"lint": "eslint .",
"prepush": "npm run lint && npm test",
"test": "jest --coverage",
"test:watch": "jest --watch"
}
}
There is also a precommit
option available but we’d rather be free to commit and avoid slowing down our development process.
Now the next time we try to push our code, husky will run the prepush
command and in our case we will be running lint
to validate our code standards and test
to run the unit tests and check the coverage.
If either of these fails, the code won’t be pushed to the remote and we will be forced to review our changes.
We did it folks,
Happy safe coding! ⛑
Who am I? / What do I do?
Hello, my name is Giovanni and I’m a Web Engineer at @ ASOS, let me know if you have any questions, comments or feedback.
You can also find me on Twitter @giovannipuntil