使用go自身的单元测试框架testing包来写单元测试有如下约束:
testing
包;_test.go
结尾;Test
开头,同时Test
后的第一字母一定要大写,如TestSpec
,写成这样Testspec
不会被框架识别;t *testing.T
。测试用例文件使用go test
指令来执行,没有也不需要 main()
作为函数入口;
所有在以_test结尾的源码内以Test开头的函数会自动被执行;
测试用例文件不会参与正常源码编译,不会被包含到可执行文件中。
go test
常见选项:
选项 | 用途 |
---|---|
-v | 显示测试的详细命令 |
-run | -run regexp,只运行 regexp 匹配的函数 |
-c | 生成 test 的二进制文件 |
使用示例:
$ go test
PASS
ok _/home/wangbm/golang/math 0.003s
$ go test math_test.go math.go
ok command-line-arguments 0.002s
-v
查看详细结果$ go test math_test.go math.go
=== RUN TestAdd
TestAdd: main_test.go:22: the result is ok
TestAdd: main_test.go:22: the result is ok
TestAdd: main_test.go:22: the result is ok
TestAdd: main_test.go:22: the result is ok
TestAdd: main_test.go:22: the result is ok
--- PASS: TestAdd (0.00s)
PASS
ok command-line-arguments 0.003s
$ go test -v -run="TestAdd"
=== RUN TestAdd
TestAdd: math_test.go:22: the result is ok
TestAdd: math_test.go:22: the result is ok
TestAdd: math_test.go:22: the result is ok
TestAdd: math_test.go:22: the result is ok
TestAdd: math_test.go:22: the result is ok
--- PASS: TestAdd (0.00s)
PASS
ok _/home/wangbm/golang/math 0.003s
-c
参数 $ go test -v -run="TestAdd" -c
$
$ ls -l
total 3208
-rw-r--r-- 1 root root 95 May 25 20:56 math.go
-rwxr-xr-x 1 root root 3272760 May 25 21:00 math.test
-rw-r--r-- 1 root root 525 May 25 20:56 math_test.go
使用goland
来写单元测试时,需要添加一个Go Test
的配置,否则无法在goland
里面运行测试。
代码可以从github下载:recipes/go/fizzbuzzwhizz at main · yanxicheung/recipes (github.com)
package main
import (
"testing"
)
func TestSpec_Example_Succ1(t *testing.T) {
t.Log("example go test1")
cases := []struct {
input int
expected string
}{{1, "1"},
{5, "Buzz"},
{30, "Fizz"},
{105, "FizzBuzzWhizz"},
}
r := spec(3, 5, 7)
for _, elem := range cases {
actual := r(elem.input)
if actual != elem.expected {
t.Errorf("failed! input %d, expected %v, actual %v", elem.input, elem.expected, actual)
}
}
}
//一个测试用例还可以分为多个子测试用例
func TestSpec_Example_Succ2(t *testing.T) {
r := spec(3, 5, 7)
t.Run("should_times_succ", func(t *testing.T) {
cases := []struct {
input int
expected string
}{
{3, "Fizz"},
{5, "Buzz"},
{7, "Whizz"}}
for _,elem:=range cases{
actual:=r(elem.input)
if actual != elem.expected {
t.Errorf("failed! input %d, expected %v, actual %v", elem.input, elem.expected, actual)
}
}
})
t.Run("should_contains_succ", func(t *testing.T) {
cases := []struct {
input int
expected string
}{
{30, "Fizz"},
{31, "Fizz"},
}
for _,elem:=range cases{
actual:=r(elem.input)
if actual != elem.expected {
t.Errorf("failed! input %d, expected %v, actual %v", elem.input, elem.expected, actual)
}
}
})
}