This page looks best with JavaScript enabled

Run Unit Test Before Every Commit with pre-commit Hook

 ·   ·  ☕ 3 min read

Introduction

Why wait for CI/CD services to run your test? And in case you’ve already submitted a pull request, you’ll have to push another commit to fix the cause of failed test held by CI provider. You can prevent that by running unit tests locally before every commit.

I’m building my website using the golang. On every git push, Travis CI runs test and create a docker image and pushes it to DockerHub. My plan is to pull that image every time it is pushed and deploy it to some production server.

Failed Travis build.

Failed Travis build.

One thing I’ve learned about this deployment system is, once I push my repo to GitHub and wait for the image to be pushed to DockerHub. I’m not sure if the test will pass and the image will be pushed. I have to open TravisCI every time I’ve to make sure.

Now I’ll show what workflow I use to to get this done.

Step by Step Setup

Inside your git repo, under .git/hooks, you’ll see git hook scripts. These are the scripts which run on a particular kind of event which git emits. The name of each file represents an event in git, and every time that event occurs, that script is run.

Contents of .git/hooks

Contents of .git/hooks

To make the hooks active, you’ll have to rename the file and remove the .sample extension.

mv .git/hooks/pre-commit.sample .git/hooks/pre-commit
mv .git/hooks/

The sample files might have already some content in them. You can safely remove them and start fresh.

Although the default file type kept inside the hooks directory is bash. You can run whatever file type you want. For example, python, ruby. Basically, anything your development machine has available. Just make sure you put proper hashbang. Following is an example of a bash script.

#!/usr/bin/sh

echo Running pre-commit hook
echo PWD is $PWD
go test -v

What Command do You Use to Run Tests

go test -v can be replaced with anything which you use to execute your test.

Make sure the file is executable by running chmod +x <file>. The pre-commit hook works on the basis of exit codes. If the test failed, the exit code will be not 0. Which means something is wrong (test failed in this case). And the commit will halt there.

Pushing the image to Docker Hub on success.

Passed Travis build.

Now I’m 100% sure my build will always pass and docker image will always be pushed to DockerHub.

Conclusion

Depending on your workflow, you might or not like way there is an additional time required to wait for the commit, but there are a plethora of possibilities with pre-commit hooks. Like linting your code, running a code format tool over it (go fmt), or anything else you would like to do with your life before commit.

Resources

Share on

Santosh Kumar
WRITTEN BY
Santosh Kumar
Fullstack Developer at Method Studios