一、Test Coverage 覆盖率
测试覆盖率是度量代码测试详尽程度的指标,它指出了被测试的代码在全部代码中所占的百分比,Go 的 testing
标准库中也提供了测试覆盖率的指标。
我们以 tango.go 文件中的三个函数为测试目标,新建一个文件 tango_coverage_test.go 将其中两个函数进行测试。
package main import ( "testing" ) func TestStringFromAssignment(t *testing.T) { StringFromBuffer(10) } func TestStringFromAppendJoin(t *testing.T) { StringFromAppendJoin(10) } 复制代码
在命令行中输入 go test -cover
执行测试并获取测试覆盖率
$ go test -cover -v tango_coverage_test.go tango.go === RUN TestStringFromAssignment --- PASS: TestStringFromAssignment (0.00s) === RUN TestStringFromAppendJoin --- PASS: TestStringFromAppendJoin (0.00s) PASS coverage: 66.7% of statements ok command-line-arguments 0.402s coverage: 66.7% of statements 复制代码
命令执行结果表明测试都已经通过,但是覆盖率只有 66.7%,并未达到 100%。
二、测试验证 ExampleXxx
testing
标准库除了提供测试功能外还提供了验证的功能,验证相关的函数都是以 ExampleXxx
命名的。
新建一个 whiskey.go 文件,输入如下代码:
package main import "fmt" func ExampleHallo() { fmt.Println("Hallo") // Output: Hallo } 复制代码
执行该测试
=== RUN ExampleHallo --- PASS: ExampleHallo (0.00s) PASS 复制代码
根据输出,我们可以确定测试通过了,将注释内容改为 // Output: Hello
再次执行测试。
=== RUN ExampleHallo --- FAIL: ExampleHallo (0.00s) got: Hallo want: Hello FAIL 复制代码
测试函数包含以 “Output:” 开头的行注释,在运行测试时,Go 会将测试函数的输出和 “Output:” 注释中的值做比较,如果两个值不同等,则测试会执行失败并输出实际结果和 Output
注释中的值。
我们以 zulu.go
中的 Add
函数为例,新建一个 whiskey.go 文件。
// filename: zulu.go func Add(x, y int) int { return x + y } 复制代码
// filename: whiskey.go func ExampleAdd() { res := Add(1, 2) fmt.Println(res) // Output: 5 } 复制代码
执行 whiskey.go 中的测试。
=== RUN ExampleAdd --- FAIL: ExampleAdd (0.00s) got: 3 want: 5 FAIL 复制代码
要注意验证函数的命名一定要符合规范 ExampleXxx
且该函数没有任何参数。
如果输出顺序可能不确定,比如循环输出 map 的值,那么可以使用 “Unordered output:” 开头的注释来作为比较的结果。
三、嵌套测试 Subtest
testing.T
和 testing.B
的 Run
方法允许定义子单元测试和子基准测试,而不必为它们单独定义函数,并且这些子测试共享通用 setup
和 tear-down
方法。
func TestXxx(t *testing.T) { t.Run("A=1", func(t *testing.T) { // 测试代码 }) t.Run("B=2", func(t *testing.T) { // 测试代码 }) t.Run("C=3", func(t *testing.T) { // 测试代码 }) } 复制代码
执行时使用 -run
参数来执行运行的子测试
go test -run '' # 执行所有测试。 go test -run Xxx # 执行匹配 "Xxx" 的顶层测试,例如 "TestXxx"。 go test -run Xxx/A= # 对于匹配 "Xxx" 的顶层测试,执行其匹配 "A=" 的子测试。 go test -run /A=1 # 执行所有匹配 "A=1" 的子测试。