1. Testing in Go
Go has a built-in testing command called
go test
and a package testing
which combine to give a minimal but complete testing experience.The standard tool-chain also includes benchmarking and statement-based code coverage similar to NCover (.NET) or Istanbul (Node.js).
1.2 Writing tests
Unit testing in Go is just as opinionated as any other aspect of the language like formatting or naming. The syntax deliberately avoids the use of assertions and leaves the responsibility for checking values and behaviour to the developer.
Here is an example of a method we want to test in the
main
package. We have defined an exported function called Sum
which takes in two integers and adds them together.package main
func Sum(x int, y int) int {
return x + y
}
func main() {
Sum(5, 5)
}
We then write our test in a separate file. The test file can be in a different package (and folder) or the same one (
main
). Here's a unit test to check addition:package main
import "testing"
func TestSum(t *testing.T) {
total := Sum(5, 5)
if total != 10 {
t.Errorf("Sum was incorrect, got: %d, want: %d.", total, 10)
}
}
Characteristics of a Golang test function:
- The first and only parameter needs to be
t *testing.T
- It begins with the word Test followed by a word or phrase starting with a capital letter.
- (usually the method under test i.e.
TestValidateClient
)
- (usually the method under test i.e.
- Calls
t.Error
ort.Fail
to indicate a failure (I called t.Errorf to provide more details)t.Log
can be used to provide non-failing debug information
- Must be saved in a file named
something_test.go
such as:addition_test.go
If you have code and tests in the same folder then you cannot execute your program withgo run *.go
. I tend to usego build
to create a binary and then I run that.
You may be more used to using the
Assert
keyword to perform checking, but the authors of The Go Programming Language make some good arguments for Go's style over Assertions.When using assertions:
- tests can feel like they're written in a different language (RSpec/Mocha for instance)
- errors can be cryptic "assert: 0 == 1"
- pages of stack traces can be generated
- tests stop executing after the first assert fails - masking patterns of failure
There are third-party libraries that replicate the feel of RSpec or Assert. See also stretchr/testify.
Test tables
The concept of "test tables" is a set (slice array) of test input and output values. Here is an example for the
Sum
function:package main
import "testing"
func TestSum(t *testing.T) {
tables := []struct {
x int
y int
n int
}{
{1, 1, 2},
{1, 2, 3},
{2, 2, 4},
{5, 2, 7},
}
for _, table := range tables {
total := Sum(table.x, table.y)
if total != table.n {
t.Errorf("Sum of (%d+%d) was incorrect, got: %d, want: %d.", table.x, table.y, total, table.n)
}
}
}
If you want to trigger the errors to break the test then alter the
Sum
function to return x * y
.$ go test -v
=== RUN TestSum
--- FAIL: TestSum (0.00s)
table_test.go:19: Sum of (1+1) was incorrect, got: 1, want: 2.
table_test.go:19: Sum of (1+2) was incorrect, got: 2, want: 3.
table_test.go:19: Sum of (5+2) was incorrect, got: 10, want: 7.
FAIL
exit status 1
FAIL github.com/alexellis/t6 0.013s
0 Response to " Golang basics - Writing Unit Tests (Part 1)"
Posting Komentar