Go has a built-in testing command go test and a package testing which gives a minimal but complete testing flow.

Function to Test

Below there is an example method we want to test in the main package. We defined an exported function called Sum which takes two integers and adds them together.

package main

import "fmt"

func Sum(x, y int) int {
	return x + y
}

func main() {
	sum := Sum(13, 29)
	fmt.Println("Sum is", sum)
}

Test

In Go we write our tests in a separate file. The test file can be in a different package —and folder or in the same one —main. Here’s our unit test for main.go:

package main

import "testing"

func TestSum(t *testing.T) {
	sum := Sum(13, 29)
	if sum != 42 {
		t.Errorf("Sum not correct: got %d, want %d", sum, 42)
	}
}

Main rules of Golang testing:

  • The first and only parameter needs to be t *testing.T
  • It begins with Test followed by a word starting with a capital letter: TestSum
  • Calls t.Error or t.Fail to show a failure
  • Tests must be saved in a file named *_test.go such as: sum_test.go

Run Tests

To run test(s), simply write:

$ go test
PASS
ok      github.com/serhatteker/unit-testing-basics  0.001s

This picks up any files matching *_test.go.

In order to get verbose output use -v flag:

$ go test -v
=== RUN   TestSum
--- PASS: TestSum (0.00s)
PASS
ok      github.com/serhatteker/unit-testing-basics  0.001s

Table Driven Test

The concept of table driven test is a set —slice array, of test input (got) values and output (wanted) value:

package main

import "testing"

func TestSum(t *testing.T) {
	tables := []struct {
		x int
		y int
		s int
	}{
		{13, 29, 42},
		{0, 9, 9},
		{1, 2, 3},
		{5, -2, 3},
	}

	for _, table := range tables {
		sum := Sum(table.x, table.y)
		if sum != table.s {
			t.Errorf("Sum of (%d+%d) not correct, got: %d, want: %d.", table.x, table.y, sum, table.s)
		}
	}
}

Coverage

The go test tool has built-in code coverage. To try it with above example type:

$ go test -cover
PASS
coverage: 33.3% of statements
ok      github.com/serhatteker/unit-testing-basics  0.001s

Html Coverage Report

If you use the below two commands you generate coverage.html report that visualises which parts of your program covered and not covered by the tests:

$ go test -cover -coverprofile=coverage.out
$ go tool cover -html=coverage.out -o coverage.html

The generated report will be like:

unit testing basics golang

All done!