Tests in Go

Learn some of the test features in Go, including subtests, table-driven tests, and flags.

Go has some fantastic features for tests that are worth mentioning.

Subtests

Subtests help us write more structured test code. Let’s use an example to understand this:

Press + to interact
package subtests
import (
"fmt"
)
type Person struct {
age int
}
func NewPerson(age int) (*Person, error) {
if age < 0 {
return nil, fmt.Errorf("age cannot be less than 0")
}
return &Person{age: age}, nil
}

For the rest of the lesson, we’ll rely on this production function for writing tests. The NewPerson function has two branches to cover:

  • The happy one is when we provide a valid age.
  • The bad one is when we pass an invalid age.

With that being said, we have to write two test functions that we’ll call TestNewPerson_WithValidAge and TestNewPerson_WithNotValidAge. Hopefully, subtests provide us with a better approach. Let’s see this in the code below:

package subtests

import "testing"

func TestNewPerson(t *testing.T) {
	t.Run("MustReturnPerson_WhenAValidAgeIsPassed", func(t *testing.T) {
		age := 18
		got, err := NewPerson(age)
		if err != nil {
			t.Errorf("err not expected but got %q", err.Error())
		}
		if got == nil {
			t.Fatal("got expected to be not nil")
		}
		if got.age != age {
			t.Errorf("age expected to be %d but got %d", age, got.age)
		}
	})

	t.Run("MustReturnErr_WhenANotValidAgeIsPassed", func(t *testing.T) {
		age := -5
		expectedErr := "age cannot be less than 0"
		got, err := NewPerson(age)
		if err == nil {
			t.Fatal("err not expected to be nil")
		}
		if err.Error() != expectedErr {
			t.Errorf("expected err was %q but got %q", expectedErr, err.Error())
		}
		if got != nil {
			t.Error("got expected to be nil")
		}
	})
}
Example of subtests

Thanks to the t.Run function, we’re able to create a parent-child structure in our test code. In fact, the parent ...