Writing unit test in Go to check code format with Travis CI

Hi! Today I will cover something that I should have done earlier in one of my projects and I was postponing: unit test to check code formating. After I committed my code twice and I had forgotten to run go fmt ., I knew something had to be done. The red flag was staring at me.

Why did I decide to write a unit test for this problem? Aren’t there better solutions? There could be better solutions and I know there are complementary solutions which would improve this one. This solution, though, is simple and gives us a visual and quick response whether you have a problem in your code or not.

An example of a complementary solution would be to use a git hook! Git hooks don’t propagate with your repository, but once you configure them they are a very nice tool for this purpose. All you have to do is create the script in .git/hooks/pre-commit and make your script be executable (chmod +x .git/hooks/pre-commit), although it is executable by default. Example of a script using go fmt:


echo "Checking formatting..."
if [ -n "$(gofmt -s -l .)" ]; then
    echo "Code is not formatted. Run 'gofmt -w .'"
    exit 1
exit 0

That’s it! Now once you run git commit this script will run right before it.

Back to the unit test talk. I couldn’t find what I was looking for and that’s why I’m writing it here. All I want to do is check with travis if my code is well formatted. For that I need the unit test. This is how I did it for my game engine, macaw:

package macaw

import "testing"
import "os/exec"

func TestGoFmt(t *testing.T) {
    cmd := exec.Command("gofmt", "-l", ".")

    if out, err := cmd.Output(); err != nil {
        if len(out) > 0 {
            t.Fatalf("Exit error: %v", err)
    } else {
        if len(out) > 0 {
            t.Fatal("You need to run go fmt")

Little explanation: first we run the gofmt command tool with the list argument. This won’t write on any file, but rather list the files that need to be formatted. Then we check whether there were errors or not, if no errors occurred we check if there are files in the output of gofmt! That’s it!

All that is left for us is to configure travis to run the code above (and other tests).

If your project doesn’t have dependencies all you need to add in your travis.yml is the following:

language: go

  - "1.x"
  - "1.8"
  - "1.10.x"
  - master

script: go test ./...

You can see more options on https://docs.travis-ci.com/user/languages/go/

That’s it. For this project I’m working on I had to download some dependencies. Here is the link if you want to check my travis.yml.