You don't test in Go using main
. Go has its own test framework.
First, read "How to Write Go Code" which will explain Go's package layout and testing tools. It's best to go with them because so much of the Go tools expect that layout.
When creating a package, put it somewhere in ~/go/src
. I'd recommend following the convention using the repository you like to use, even for things you aren't necessarily going to upload. It makes for better organization; go get
will put other external packages in ~/go/src/
as well.
For example, I'd use ~/go/src/github.com/schwern/newpackage/
even though I don't intend to upload this to Github. github.com/schwern
acts as my "organization" within the Go source tree.
Put the functions into newpackage.go
under package newpackage
.
$ cat ~/go/src/github.com/schwern/newpackage/newpackage.go
package newpackage
func MyNewFunc() string {
return "Hello!"
}
Then tests go in newpackage_test.go
right next to newpackage.go
. These should be familiar from Python, write a bunch of Test* functions. Unlike Python it doesn't use asserts.
$ cat ~/go/src/github.com/schwern/newpackage/newpackage_test.go
package newpackage_test
import(
"testing"
"github.com/schwern/newpackage"
)
func TestMyNewFunc( t *testing.T ) {
want := "Hello!"
have := newpackage.MyNewFunc()
if have != want {
t.Errorf("MyNewFunc(): have: '%v', want: '%v'", have, want )
}
}
If you run go test
inside the package directory it will compile the current package and its dependencies, find and compile all *_test.go
files in the package directory, and execute their Test*
functions.
$ pwd
/Users/schwern/go/src/github.com/schwern/newpackage
$ go test -v
=== RUN TestMyNewFunc
--- PASS: TestMyNewFunc (0.00s)
PASS
ok github.com/schwern/newpackage 0.013s
Note that the test is in a different package than what its testing. That makes it a blackbox test, it can only see the exported (ie. UpperCase) functions. You can make a glassbox test by putting the tests in the same package, it's best to do that in a separate file like newpackage_internal_test.go
.
Unfortunately Go doesn't come with assert functions, the above if
and call to t.Errorf
is the equivalent. Rather than constantly hand-roll them, there's libraries out there which provide assert functions like stvp/assert. After running go get github.com/stvp/assert
you could write...
package newpackage_test
import(
"testing"
"github.com/schwern/newpackage"
"github.com/stvp/assert"
)
func TestMyNewFunc( t *testing.T ) {
assert.Equal( t, newpackage.MyNewFunc(), "Hello!" )
}
If you want an executable that uses newpackage
, it should probably go in its own package. Unless it's an integral part of newpackage
.
$ cat ~/go/src/github.com/schwern/newexec/main.go
package main
import (
"fmt"
"github.com/schwern/newpackage"
)
func main() {
fmt.Println(newpackage.MyNewFunc())
}
If you want to test main
, the testing
package provides a special TestMain
function... though I admit I do not fully understand it. Like any other language, it's best to put as much functionality as possible into library calls and have main
be a thin wrapper.