Implementation of unit testing using Go
- 2020-09-28 08:55:55
- OfStack
Introduction to the
In daily development, testing is indispensable.
The Go standard library includes a testing framework called testing that can be used for both unit and performance testing.
It is integrated with the command go test.
The test file is named after the suffix _test.go and is usually in the same package as the file under test.
Unit testing
The format of unit tests is as follows:
func TestAbs(t *testing.T) {
got := Abs(-1)
if got != 1 {
t.Errorf("Abs(-1) = %d; want 1", got)
}
}
Create 1 file es30EN_ES31en.go in util directory, add 1 unit test:
package util
import "testing"
// Normal test
func TestGenShortID(t *testing.T) {
shortID, err := GenShortID()
if shortID == "" || err != nil {
t.Error("GenShortID failed")
}
}
Then, run go ES38en-ES39en./util/ in the root directory. The test results are as follows:
root@592402321ce7:/workspace# go test -v ./util/
=== RUN TestGenShortID
--- PASS: TestGenShortID (0.00s)
PASS
ok tzh.com/web/util 0.006s
The performance test
The performance test results are as follows:
func BenchmarkHello(b *testing.B) {
for i := 0; i < b.N; i++ {
fmt.Sprintf("hello")
}
}
Add performance tests in util_test.go:
// The performance test
func BenchmarkGenShortID(b *testing.B) {
for i := 0; i < b.N; i++ {
GenShortID()
}
}
The results of the run are as follows (avoid running normal test functions using --run=none, as it is not possible for function names to match none in 1):
root@592402321ce7:/workspace# go test -v -bench="BenchmarkGenShortID$" --run=none ./util/
goos: linux
goarch: amd64
pkg: tzh.com/web/util
BenchmarkGenShortID-2 507237 2352 ns/op
PASS
ok tzh.com/web/util 1.229s
This means that the average running time of GenShortID() is 2352 nanoseconds.
Performance analysis
When running tests, you can specify 1 parameter to generate the performance file profile.
-blockprofile block.out
Write a goroutine blocking profile to the specified file
when all tests are complete.
Writes test binary as -c would.
-blockprofilerate n
Control the detail provided in goroutine blocking profiles by
calling runtime.SetBlockProfileRate with n.
See 'go doc runtime.SetBlockProfileRate'.
The profiler aims to sample, on average, one blocking event every
n nanoseconds the program spends blocked. By default,
if -test.blockprofile is set without this flag, all blocking events
are recorded, equivalent to -test.blockprofilerate=1.
-coverprofile cover.out
Write a coverage profile to the file after all tests have passed.
Sets -cover.
-cpuprofile cpu.out
Write a CPU profile to the specified file before exiting.
Writes test binary as -c would.
-memprofile mem.out
Write an allocation profile to the file after all tests have passed.
Writes test binary as -c would.
-memprofilerate n
Enable more precise (and expensive) memory allocation profiles by
setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'.
To profile all memory allocations, use -test.memprofilerate=1.
-mutexprofile mutex.out
Write a mutex contention profile to the specified file
when all tests are complete.
Writes test binary as -c would.
-mutexprofilefraction n
Sample 1 in n stack traces of goroutines holding a
contended mutex.
Use the following command to generate profile for CPU:
go test -v -bench="BenchmarkGenShortID$" --run=none -cpuprofile cpu.out ./util/
Under the current directory, the cpu.out file and util.test file should be generated.
Observe time-consuming operations using the following command:
# Enter interactive mode
go tool pprof cpu.out
top
After installing Graphviz, a visual analysis diagram can be generated.
apt install graphviz
go tool pprof -http=":" cpu.out
Test coverage
package util
import "testing"
// Normal test
func TestGenShortID(t *testing.T) {
shortID, err := GenShortID()
if shortID == "" || err != nil {
t.Error("GenShortID failed")
}
}
0
Use the -ES104en = ES105en.out option to count test coverage. Use go tool ES109en-ES110en = ES111en. out to see more detailed test coverage results.
Count the test coverage for each function.
conclusion
Testing is a very important part of development. It is used to ensure the quality of software.
The code for the current section
As version v0.15.0