This blog post describes basics and practical examples of go test. Go’s automated test mechanism is well designed and easy to use. I’ll show you some techniques of go test in this article.
What is go test
go test is a command to run automated tests of go packages.
- Automated test must be defined in
_test.gofile - Automated test function must start with
Testprefix
Example: stack
I implement a stack as real world example to explain go test. stack package provides stack.go. If you want to write tests for stack.go, create a file named stack_test.go. The source code is in GitHub repository.
go test [packages]
First of all, let’s test a simple function stack.NewIntStack.
package stack import "testing" func TestNewIntStack(t *testing.T) { istack := NewIntStack() if istack == nil { t.Error("NewIntStack() returns nil") } }
The test checks NewIntStack returns non nil. To run the test, type go test ./stack. You’ll get following output. It means the test succeeded.
go test ./stack ok github.com/oinume/go-test-in-practice/stack 0.136s
go test -v
-v flag enables verbose mode. You can get a message TestNewIntStack finished by running with -v flag.
func TestNewIntStack(t *testing.T) { istack := NewIntStack() if istack == nil { t.Error("NewIntStack() returns nil") } t.Log("TestNewIntStack finished") // This message is output only in verbose mode }
go test -v ./stack
=== RUN TestNewIntStack
--- PASS: TestNewIntStack (0.00s)
stack_test.go:10: TestNewIntStack finished
PASS
ok github.com/oinume/go-test-in-practice/stack 0.132s
all outputs in STDOUT are printed in verbose mode. You can use t.Log or t.Logf if you want to print a message with line number.
If you want to do something only when verbose mode, You can use testing.Verbose() in your test code.
go test -short
You can use -short flag to skip long-running tests. You can refer the flag is on or off by testing.Short() in your test.
Example:
func TestIntStack_PushALot(t *testing.T) { if testing.Short() { t.Skip("Skip pushing a lot of numbers to a stack") } istack := NewIntStack() for i := 0; i < 10000000; i++ { istack.Push(i) } }
go test -run
-run flag is used to specify tests to run. If you have test functions TestNewIntStack and TestIntStack_PushALot, you want to run only TestIntStack_PushALot. You’ll save time with -run flag in order to avoid running whole tests.
Example:
go test -run TestIntStack_PushALot ./stack === RUN TestIntStack_PushALot --- PASS: TestIntStack_PushALot (1.01s) PASS ok github.com/oinume/go-test-in-practice/stack 1.156s
reflect.DeepEqual
You can use reflect.DeepEqual to compare two values of structs. Following example ensures istack1 and istack2 are the same.
func TestIntStack_Compare(t *testing.T) { istack1 := NewIntStack() istack2 := NewIntStack() for i := range []int{1, 2, 3} { istack1.Push(i) istack2.Push(i) } if !reflect.DeepEqual(istack1, istack2) { t.Errorf("Stacks must be the same: istack1.Size=%d, istack2.Size=%d", istack1.Size(), istack2.Size()) } }
TestMain
TestMain is a main function in automated tests. Sometimes it is necessary for a test program to do extra setup or teardown before or after testing. If func TestMain(m *testing.M) function exists in your package, the generated test will call TestMain(m) instead of running the tests directly. This is an example to set up and tear down with TestMain.
func TestMain(m *testing.M) {
// Set up something for tests
status := m.Run()
// Tear down something for tests
os.Exit(status)
}
And more
go test has much more features like benchmark, example test, etc. You’ll find them out in document of testing package. There are also good slides of testing like Advanced Testing with Go // Speaker Deck.