[Day 5] JS in Pipeline (5): Testing, Linting, and Git Hooks


The goal of this series is to introduce some best practices in the local development environment and create a CI/CD pipeline for NodeJS applications.

GitHub repo for this article series: https://github.com/jeanycyang/js-in-pipeline

In this article, we will talk about testing, linting, and git hooks.


Testings

There are different types of testings, such as unit tests and integration tests. You can read more about it at https://www.atlassian.com/continuous-delivery/software-testing/types-of-software-testing.

You should test your code as it makes you more confident about your applications. The testing coverage is also very important. If you only cover a few lines of code, then if another part broke, you would not know before your customer complaints.

If you are not familiar with any types of testings, I’d recommend googling “nodejs unit test tutorial” and then learn it by writing some tests yourself :).

Now, assume that everyone is familiar with testings so that we will focus on “Testings for pipelines”. We will use Jest as our testing framework and take Unit Tests for example in this article.

There are 2 must-checks. One is the result of the test cases, and the other is coverage.

First, we set up npm test in our package.json file.

"scripts": {
  "dev": "nodemon index.js",
  "test": "ENVIRONMENT=dev jest --testRegex=tests/unit/.*.test.js$ --coverage"
},

The --coverage flag tells Jest to output coverage report after the test is finished.

Obviously, if any test case fails, the whole npm test fails. So, let’s see how to set up coverage thresholds.

Let’s create jest.config.js in the project directory. If you want to know more about the Jest configuration, you can check it on this page: https://jestjs.io/docs/en/configuration.

module.exports = {
...
  'coverageThreshold': {
    'global': {
      'statements': 95,
      'branches': 90,
      'functions': 90,
      'lines': 95,
    },
  },
};

We can set up coverageThreshold in the config file. It means, even if all the test cases pass, if your thresholds aren’t met, the whole npm test still fails.

npm test now not only makes sure all test cases pass, but also check if your test coverage meets the required thresholds.

Testings are a very important part of any pipeline. We will add npm test as one of the steps in our CI/CD pipeline in future articles and in the section “Git Hooks”.

Linting

What is Lint/Linter?

lint, or a linter, is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.
https://en.wikipedia.org/wiki/Lint_(software)

We will use ESlint, an outstanding linter for JavaScript, in this article series.

Let’s say you have a typo in your code. The variable name is length and you misspell it as lentgh somewhere. If you try to run your code, you will get “Uncaught ReferenceError: lentgh is not defined”.

This is one of the reasons why you should use a linter. A linter analyzes your code in real-time; therefore, with the help of a linter, you can find out this kind of stupid errors before you save your file or even commit your changes.

Let’s add a npm script called lint.

"lint": "eslint --fix ."

This command can automatically check all your js files and fix all the problems ESlint can fix for you. If there is any problem ESlint cannot automatically fix, the command will exit with an error.

Git Hooks

…Git has a way to fire off custom scripts when certain important actions occur.
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

They are two groups of Git Hooks, one group is Client-side, and the other is Server-Side.

Here are some Client-Side Hooks: pre-commit, commit-msg, pre-push.

Let’s take pre-commit for example. If you run git-commit command, before git really commits your changes it will run pre-commit scripts first. If the script exits non-zero, i.e. having errors, Git will abort the commit.

By Git Hooks, we can automatically run some checks (e.g. linting and testing) when a certain git action occurs!

Let’s say, our team agrees that everyone should use the same coding style (e.g. indent or trailing commas). Thus, we can run npm lint whenever a developer tries to commit changes.

You can simply create a file called pre-commit in .git/hooks directory and then make it executable (chmod +x ./git/hooks/pre-commit).

# PROJECT_DIR/.git/hooks/pre-commit
npm run lint

Super simple, Isn’t it?

Then, every time you try to commit, Git will automatically run npm run lint for you.

And let’s say the team agrees that broken codes are not ready for review. Therefore, before a developer pushes anything changes to the remote repo, we should check if the code passes all test cases. If not, then the changes are not allowed to be pushed. Also, the changes should follow the agreed coding style.

Create pre-push in .git/hooks directory and make it executable.

# PROJECT_DIR/.git/hooks/pre-push
npm run lint && npm test

Then if any of these two checks fails, the changes are not allowed to be pushed.

How to Track Git Hooks Itself?

Just creating your hooks script in .git/hooks has one serious problem -- the .git directory itself won't be tracked. This is, .git/hooks/* are ignored by git.

There are several ways to solve it.

  1. You can add a directory called hooks or gitHooks in the project directory. Then you create a script called setup.shand make it executable:
# Git Hooks Setup
cp gitHooks/* .git/hooks
# other necessary setups..
...

Run setup.sh every time you clone this repo.

Pros: Doesn't need any other plugins/packages.

Cons: You need to write it in your documentation (e.g. README.md)and to remember it.

  1. You can use npm package like Husky. Simply install it as dev-dependency and add husky in your package.json.
// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint",
      "pre-push": "npm run lint && npm test",
      "...": "..."
    }
  }
}

Pros: You won't need to remember anything. You won't develop any NodeJS application without using npm, will you? :)

Cons: Needs an extra package.


With Git Hooks, we can improve our development process and run necessary checks like linting and testing.

In the next article, finally, we can set up our CI/CD pipeline! 🎉🎉🎉


Useful Links/References

#devops #tests #lint #Git #git hooks







你可能感興趣的文章

component test 問題集4(React18 + TS + Jest + react-testing-library)

component test 問題集4(React18 + TS + Jest + react-testing-library)

Day 137

Day 137

Vue.js 學習旅程Mile 2 – 環境建置篇

Vue.js 學習旅程Mile 2 – 環境建置篇






留言討論