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.go
file - Automated test function must start with
Test
prefix
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.