第11章 测试
软件测试是一个巨大的领域,但是Go语言的测试技术是相对比较低级的,它依赖一个Go test测试命令和一组按照约定方式编写的测试函数,测试命令可以运行这些函数
在实践中,编写测试代码和编写程序本身并没有多大区别
11.1 go test
go test 命令是一个按照一定的约定和组织来测试代码的程序。在包目录内,所以有以 _test.go为后缀名的源文件在执行go build时不会被构建成包的一部分
在*_test.go文件中,有三种类型的函数,测试函数、基准测试函数、示例函数
测试函数:以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确;go test命令会调用这些测试函数并报告测试结果是fail还是success
基准测试:以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准测试函数以计算一个平均的执行时间
示例函数:以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档
go test命令会遍历所有的 *_test.go文件中符合上述命名规则的函数每,生成一个临时的main包用于调用相应的测试函数,接着构建并运行、报告测试结果,最后清理测试中生成的临时文件
11.2 测试函数
每个测试函数必须导入testing包。测试函数有如下签名
func TestName(t *testing.T) {
//...
}
测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头
func TestSin() {/*...*/}
func TestCos() {/*...*/}
func TestLog() {/*...*/}
参数t用于报告测试失败和附加的日志信息
我们现在来写一个函数,这个函数能够判断一个字符串是否对称。比如QAQ就是对称的
package word
func IsPalindrome(s string) bool {
for i := range s {
if s[i] != s[len(s)-1-i] {
return false
}
}
return true
}
然后我们在同包下面写两个测试函数用来测试这个函数是否能够正常输出
package word
import "testing"
func TestPalindrome(t *testing.T) {
if !IsPalindrome("detartrated") {
t.Error(`IsPalindrome("detartrated")=false`)
}
if !IsPalindrome("kayak") {
t.Error(`IsPalindrome("kayak")=false`)
}
}
func TestNonPalindrome(t *testing.T) {
if IsPalindrome("palindrome") {
t.Error(`IsPalindrome("palindrome")=true`)
}
}
我们来运行一下,这个操作和go build 基本是一样的
cd /Users/xxx/awesomeProject/src/word
go test
PASS
ok awesomeProject/src/word 0.594s
结果表明这个函数是通过了测试,但是这上面两个例子太简单了,我可以用更多的例子来测试一下,我们来写一下测试函数
func TestFrenchPalindrome(t *testing.T) {
if !IsPalindrome("été") {
t.Error(`IsPalindrome("été")=false`)
}
}
func TestCanaPalindrome(t *testing.T) {
input := "A man, a plan, a canal: Panama"
if !IsPalindrome(input) {
t.Errorf(`IsPalindrome(%q)=false`,input)
}
}
为了避免两次输入较长的字符串,我们使用了提供了有类似Printf格式化功能的Errorf函数来汇报错误结果
当添加了这两个测试用例后,go test返回了测试失败的信息
go test
--- FAIL: TestFrenchPalindrome (0.00s)
world_test.go:22: IsPalindrome("été")=false
--- FAIL: TestCanaPalindrome (0.00s)
world_test.go:29: IsPalindrome("A man, a plan, a canal: Panama")=false
FAIL
exit status 1
FAIL awesomeProject/src/word 0.118s
编写测试用例并且通过其获得错误信息是个非常好的习惯,它能够比手速更快的处理报告