golang单元测试简记
golang中的测试类型
类型 | 格式 | 作用 |
---|---|---|
测试函数 | 函数名前缀为Test | 测试程序的一些逻辑行为是否正确 |
基准函数 | 函数名前缀为Benchmark | 测试函数的性能 |
示例函数 | 函数名前缀为Example | 为文档提供示例文档 |
在goland中快速生成测试代码
以字符串分割函数为例,它在作用就是分割字符串,并且返回分割后的切片:
// split/split.go
package split
import "strings"
// split package with a single split function.
// Split slices s into all substrings separated by sep and
// returns a slice of the substrings between those separators.
func Split(s, sep string) (result []string) {
i := strings.Index(s, sep)
for i > -1 {
result = append(result, s[:i])
s = s[i+len(sep):]
i = strings.Index(s, sep)
}
result = append(result, s)
return
}
右击->Gernate->Tests for file
在与被测试的包相同的包中,它会创建一个名称以 _test.go 结尾的文件,该文件包含 TestXxx
函数。该文件将被排除在正常的程序包之外,但在运行 “go test” 命令时将被包含。
可以看到名为“split_test.go”的test文件,初始内容为
package split
import (
"reflect"
"testing"
)
func TestSplit(t *testing.T) {
type args struct {
s string
sep string
}
tests := []struct {
name string
args args
wantResult []string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotResult := Split(tt.args.s, tt.args.sep); !reflect.DeepEqual(gotResult, tt.wantResult) {
t.Errorf("Split() = %v, want %v", gotResult, tt.wantResult)
}
})
}
}
ps :在生成的测试代码中:
- TestXXX(t *testing.T) 表示基础测试
- TestXXX(t *testing.B) 表示基准测试
测试
添加测试用例:
package split
import (
"reflect"
"testing"
)
func TestSplit(t *testing.T) {
type args struct {
s string
sep string
}
tests := []struct {
name string
args args
wantResult []string
}{
// TODO: Add test cases.
{name: "test1",args: args{s:"a:b:c",sep: ":"},wantResult: []string{"a", "b", "c"}},
{name: "test2",args: args{s:"a:b:c",sep: ","},wantResult: []string{"a:b:c"}},
{name: "test3",args: args{s:"abcd",sep: "bc"},wantResult: []string{"a", "d"}},
{name: "test4",args: args{s:"沙河有沙又有河",sep: "沙"},wantResult: []string{"河有", "又有河"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotResult := Split(tt.args.s, tt.args.sep); !reflect.DeepEqual(gotResult, tt.wantResult) {
t.Errorf("Split() = %v, want %v", gotResult, tt.wantResult)
}
})
}
}
go test -v
执行测试: go test -v
$ go test -v
=== RUN TestSplit
=== RUN TestSplit/test1
=== RUN TestSplit/test2
=== RUN TestSplit/test3
=== RUN TestSplit/test4
split_test.go:27: Split() = [ 河有 又有河], want [河有 又有河]
--- FAIL: TestSplit (0.00s)
--- PASS: TestSplit/test1 (0.00s)
--- PASS: TestSplit/test2 (0.00s)
--- PASS: TestSplit/test3 (0.00s)
--- FAIL: TestSplit/test4 (0.00s)
FAIL
exit status 1
FAIL GoTestDemo02/split 0.925s
若只想要测试名称为test4的用例,需要添加“-run”参数,并且写上子测试的名称,关于子测试,官方是这样解释的:
每个子测试和子基准测试都有一个唯一的名称:顶级测试的名称和传递给 Run 的名称的组合,以斜杠分隔,并具有用于消歧的可选尾随序列号。
-run 和 -bench 命令行标志的参数是与测试名称相匹配的非固定的正则表达式。对于具有多个斜杠分隔元素(例如子测试)的测试,该参数本身是斜杠分隔的,其中表达式依次匹配每个名称元素。因为它是非固定的,一个空的表达式匹配任何字符串。例如,使用 "匹配" 表示 "其名称包含":
go test -run '' # Run 所有测试。 go test -run Foo # Run 匹配 "Foo" 的顶层测试,例如 "TestFooBar"。 go test -run Foo/A= # 匹配顶层测试 "Foo",运行其匹配 "A=" 的子测试。 go test -run /A=1 # 运行所有匹配 "A=1" 的子测试。
这里,我们可以这样做:
$ go test -v -run Split/test4
=== RUN TestSplit
=== RUN TestSplit/test4
split_test.go:27: Split() = [ 河有 又有河], want [河有 又有河]
--- FAIL: TestSplit (0.00s)
--- FAIL: TestSplit/test4 (0.00s)
FAIL
exit status 1
FAIL GoTestDemo02/split 0.931s
go test -cover:测试覆盖率
$ go test -cover
PASS
coverage: 100.0% of statements
ok GoTestDemo02/split 0.644s
若想要让以HTML形式展示覆盖率:
$ go test -cover -coverprofile=c.out
PASS
coverage: 100.0% of statements
ok GoTestDemo02/split 0.849s
$go tool cover -html=c.out
参考链接:
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程