Unit Testing
https://blog.jetbrains.com/go/2022/11/22/comprehensive-guide-to-testing-in-go
How to do unit testing
Create file
project_test.go
The test function signature is
TestXXX(t *testing.T)
Those two steps are the only mandatory step to create unit testing. But we can follow some best practices to structure our tests and test cases:
Structure our test as test tables with many test cases
Properly assert the function behavior
Name test cases as descriptive as possible
Useful Commands
Use
go test -race ./...
to run the unit test with a check for a race conditionUse
go tool cover -func=coverage.out
to display coverage information on the terminal consoleUse
go tool cover -html=coverage.out
to display the coverage information on HTML format in browser.
Examples
package main
import "strconv"
// If the number is divisible by 3, write "Foo" otherwise, the number
func Fooer(input int) string {
isfoo := (input % 3) == 0
if isfoo {
return "Foo"
}
return strconv.Itoa(input)
}
project_test.go
package main
import "testing"
func TestFooer(t *testing.T) {
result := Fooer(3)
if result != "Foo" {
t.Errorf("Result was incorrect, got: %s, want: %s.", result, "Foo")
}
}
Table Driven testing
func TestFooerTableDriven(t *testing.T) {
// Defining the columns of the table
var tests = []struct {
name string
input int
want string
}{
// the table itself
{"9 should be Foo", 9, "Foo"},
{"3 should be Foo", 3, "Foo"},
{"1 is not Foo", 1, "1"},
{"0 should be Foo", 0, "Foo"},
}
// The execution loop
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ans := Fooer(tt.input)
if ans != tt.want {
t.Errorf("got %s, want %s", ans, tt.want)
}
})
}
}
Errors and Logs
func TestFooer2(t *testing.T) {
input := 3
result := Fooer(3)
t.Logf("The input was %d", input)
if result != "Foo" {
t.Errorf("Result was incorrect, got: %s, want: %s.", result, "Foo")
}
t.Fatalf("Stop the test now, we have seen enough")
t.Error("This won't be executed")
}
Running Parallel Tests
The following code will test Fooer(3)
and Fooer(7)
at the same time
func TestFooerParallel(t *testing.T) {
t.Run("Test 3 in Parallel", func(t *testing.T) {
t.Parallel()
result := Fooer(3)
if result != "Foo" {
t.Errorf("Result was incorrect, got: %s, want: %s.", result, "Foo")
}
})
t.Run("Test 7 in Parallel", func(t *testing.T) {
t.Parallel()
result := Fooer(7)
if result != "7" {
t.Errorf("Result was incorrect, got: %s, want: %s.", result, "7")
}
})
}
Skipping Tests
func TestFooerSkiped(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
result := Fooer(3)
if result != "Foo" {
t.Errorf("Result was incorrect, got: %s, want: %s.", result, "Foo")
}
}
Last updated
Was this helpful?