3 min read

How Automation Saved Me from Oops Moments: Never Skip Tests in Production Again!

How Automation Saved Me from Oops Moments: Never Skip Tests in Production Again!

Every time I have to troubleshoot and fix a unit test (or Cypress test), I end up running just that one test locally—using the .only suffix in my test case. This syntax allows me to ignore all other tests in the same file, which is exactly what I need at the moment.

But you might know the feeling—sometimes I am just too excited that I finally managed to fix the problem, and I forget to remove the .only from the test case. And since we are all humans, the colleague who does the code review might also just not notice it, and it makes its way to production. As a result, we end up skipping some of tests because of a small mistake. 😬

As a developer, I prefer to write code that helps me avoid all the boring stuff and also spot issues like this. So, I decided I wanted to have some automation in place that would help catch this issue and fit into our project workflow. In this article, I want to share my solution with you; maybe it might inspire you to automate the same or a similar problem you might be facing.

I decided to address this problem on two levels:

  • Write a pre-commit hook that will notify the developer about this issue.
  • Write a GitHub action that will run for every pull request.

Pre-commit hook

We were already using lint-staged and have a pre-commit hook in place using Husky in our project for linter and prettier. So it made sense to add a check here.

So first I created a file pre-commit.sh which is a bash script that checks all the staged files and looks for the .only text.

Then I just had to specify for which files I want to run this script in my lint-staged.config.jsconfiguration file. In my case I wanted to run the script only for the JavaScript and TypeScript files.

(For simplicity the code snippet below contains only my custom script).

module.exports = {
  "*.{js,jsx}": ["bash pre-commit.sh"],
  "*.{ts,tsx}": ["bash pre-commit.sh"],
};

In my case both files, the configuration and the script, were on the same level in my file structure. Otherwise I would have to specify the relative path to the script.

Perfect! Now we have a check in place for every commit made by a developer… but wait, what if a developer decides to just ignore the warning (using the --no-verify flag for a commit) or does not install the pre-commit hook locally at all? 🤔

GitHub action for each Pull Request

This scenario can be addressed by a GitHub Action that runs on every pull request to the main branch. I've added a new job to the workflow to perform a similar check. However, I had to make some adjustments to the script. The one I initially used for pre-commit hooks compares the staged files. Considering that there could be multiple commits in the pull request, and some of them might involve force pushes, I wanted to ensure a thorough comparison of all the JavaScript and TypeScript files modified in the pull request.

Yes, automation can save us a lot of time and help avoid issues caused by silly mistakes.