🐹 Go - Unit Testing
Updated at 2022-04-21 09:55
My other snippets related to testing:
Go has build-in unit testing.
- Test file names should end with
_test.go
e.g.main_test.go
. - Test file should be next to the file it tests or in the package directory it tests.
- Test function names should start with
Test
e.g.TestPasses
. - Run all tests in a directory with
go test ./dir
orgo test .
. - Run all tests with
go test ./...
at the project root.
package main
import (
"fmt"
"testing"
)
func TestThatPasses(t *testing.T) {
// passes as nothing fails the test
}
func TestThatFails(t *testing.T) {
t.Fail()
}
func TestThatFailsWithMessage(t *testing.T) {
t.Errorf("This failed: %s!", "nothing")
}
func TestWithTableDrivenParametrization(t *testing.T) {
// the test case table could also be a separate variable
for _, tc := range []struct {
a, b int
aIsBigger bool
}{
{0, 1, false},
{1, 0, true},
{2, -2, true},
{0, -1, true},
{-1, 0, false},
} {
name := fmt.Sprintf("%d_>_%d", tc.a, tc.b) // spaces are not allowed
t.Run(name, func(t *testing.T) { // runs a separate subtest
ans := tc.a > tc.b
if ans != tc.aIsBigger {
t.Errorf("got %t, wanted %t", ans, tc.aIsBigger)
}
})
}
}
// you can also create benchmarks through `testing.B`
// note that the benchmark must start with `Benchmark`
// and should use the `b.N` as the loop count
// you run benchmarks with `go test -bench .`
func BenchmarkComparison(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = i > 2 // here would be the call to your code
}
}
You can test processes. Simply use exec.Command
to run a process and inspect the outcome. Can be used to unit test your command line workings or do some more elaborate integration tests.
package main
import (
"fmt"
"os"
"os/exec"
"testing"
)
func Crasher() {
fmt.Println("going down in flames")
os.Exit(1)
}
func TestCrasher(t *testing.T) {
if os.Getenv("BE_CRASHER") == "1" {
Crasher()
return
}
cmd := exec.Command(os.Args[0], "-test.run=TestCrasher")
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
err := cmd.Run()
if e, ok := err.(*exec.ExitError); ok && e.ExitCode() == 1 {
return
}
t.Fatalf("process ran with err %q, want exit status 1", err)
}