测试源码文件的主名称应该以被测试源码文件的主名称为前导,并且以”_test“为后缀。
Go 语言对测试函数的名称和签名的规定:
- 对于功能测试函数,名称前缀必须为 Test,唯一参数类型为 *testing.T
- 对于性能测试函数,名称前缀必须为 Benchmark,唯一参数类型为 *testing.B
- 对于示例测试函数,名称前缀必须为 Example,参数没有规定。
只有测试源码文件的名称对了,测试函数的名称和签名也对了,运行“go test 目录”命令时,测试代码才会被运行。
功能测试
demo.go
package main
import (
"fmt"
"errors"
"flag"
)
var name string
func init() {
flag.StringVar(&name, "name", "everyone", "The greeting object.")
}
func main() {
flag.Parse()
greeting, err := hello(name)
if err != nil {
fmt.Printf("error: %s\n", err)
return
}
fmt.Println(greeting, introduce())
}
func hello(name string) (string, error) {
if name == "" {
return "", errors.New("empty name")
}
return fmt.Sprintf("Hello, %s!", name), nil
}
func introduce() string {
return "Welcome to school."
}
demo_test.go
package main
import (
"fmt"
"testing"
)
func TestHello(t *testing.T) {
var name string
greeting, err := hello(name)
if err == nil {
t.Errorf("The error is nil, but it should not be. (name = %q)", name) // 测试失败的同时打印测试日志
}
if greeting != "" {
t.Errorf("Nonempty greeting, but it should not be. (name = %q)", name)
}
name = "Robert"
greeting, err = hello(name)
if err != nil {
t.Errorf("The error is not nil, but it should be. (name = %q)", name)
}
if greeting == "" {
t.Errorf("Empty greeting, but it should not be. (name=%q)", name)
}
expected := fmt.Sprintf("Hello, %s!", name)
if greeting != expected {
t.Errorf("The actual greeting %q is not the expected. (name=%q)", greeting, name)
}
t.Logf("The expected greeting is %q.\n", expected) // 常规测试日志,加参数 -v 可看到
}
func TestIntroduce(t *testing.T) {
intro := introduce()
expected := "Wellcome to school."
if intro != expected {
t.Errorf("The actual introduce %q is not the expected.", intro)
}
t.Logf("The expected introduce is %q.\n", expected)
}
./ 表示当前目录
改一下 demo.go
func introduce() string {
return "Wellcome to school."
}
加上 -v,可看到 t.log 和 t.logf 打印的常规测试日志。
性能测试
demo.go
package main
func Add(num int) int{
return num + num
}
demo_test.go
package main
import (
"testing"
)
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(i)
}
}
-bench=. 中的 . 表示要执行任意名称的性能测试函数。
-run=^$ 用于表面需要执行那些功能测试函数,^$ 表示只执行名称为空的功能测试函数,即不执行功能测试函数。
如果不加 -run,表示执行被测试代码包中的所有功能测试函数。
结果中,BenchmarkAdd-8 为单个性能测试的名称,使用的最大逻辑 CPU 个数为 8。
2000000000 为被测函数的被执行次数。
go test 命令会先尝试把 b.N 设置为 1,如果测试函数的执行时间没有超过上限(默认为 1s),则增大 b.N 的值,继续测试,直到时间 >= 上限为止。
b.N 是被测函数的执行次数,而不是性能函数的执行次数。
go test 的其它参数:
-cpu,指定逻辑 CPU 数。
-count,用于重复执行测试函数的次数。
-parallel,设置同一被测代码包中的功能测试函数的最大并发执行数。