【声明】
非完全原创,部分内容来自于学习其他人的理论和B站视频。如果有侵权,请联系我,可以立即删除掉。
一、单元测试
为什么需要单元测试
(1)如果按照传统的测试方法,则需要在main函数种添加测试项,如果项目正在运行,则需要停止项目
(2)如果需要测试多个函数或者模块,则需要全部写在main函数中,不利于项目的管理
(3)go语言自带单元测试框架,可以解决上述问题
下面转载自:https://www.cnblogs.com/zongmin/p/16365976.html
在go语言中,一般使用go test
命令进行函数测试,包目录下所有以_test.go
为后缀的文件都是go test测试的一部分,不会被go build编译到最终的可执行文件。_test.go
中的测试函数主要分为3种:
类型 | 格式 | 作用 |
---|---|---|
测试函数 | 函数名前缀为Test | 测试程序的一些逻辑行为是否正确 |
基准函数 | 函数名前缀为Benchmark | 测试函数的性能 |
示例函数 | 函数名前缀为Example | 为文档提供示例文档 |
1、相关测试方法
1.1、单元测试的函数
func (c *T) Error(args ...interface{
})
func (c *T) Errorf(format string, args ...interface{
})
func (c *T) Fatal(args ...interface{
})
func (c *T) Fatalf(format string, args ...interface{
})
func (c *T) Log(args ...interface{
})
func (c *T) Logf(format string, args ...interface{
})
func (t *T) Parallel()
//Parallel 用于表示当前测试只会与其他带有 Parallel 方法的测试并行进行测试。
func (t *T) Run(name string, f func(t *T)) bool
//执行名字为 name 的子测试 f ,并报告 f 在执行过程中是否出现了任何失败。Run 将一直阻塞直到 f 的所有并行测试执行完毕
func (c *T) Skip(args ...interface{
})
//将当前测试标识为“被跳过”并停止执行该测试
1.2、t.Skip() 方法
// 为了节省时间支持在单元测试时跳过某些耗时的测试用例
func TestTimeConsuming(t *testing.T) {
if testing.Short() {
t.Skip("short模式下会跳过该测试用例")
}
...
}
当执行go test -short
时就不会执行上面的TestTimeConsuming
测试用例。
2、测试示例
2.1、基本使用
2.1.1、测试的文件
(1)待测试函数的文件
//cal.go
package cal
func add(n int) int {
return (n + 1) * n / 2
}
func multi(n uint64) uint64 {
if n == 1 {
return 1
}
return n * multi(n-1)
}
func fiber(n int) int {
if n == 1 || n == 2 {
return 1
}
return fiber(n-1) + fiber(n-2)
}
(2)测试函数文件1
//cal_test.go
package cal
import (
"testing"
)
func TestAdd(t *testing.T) {
res := add(10)
if res != 55 {
t.Fatalf("TestAdd执行失败, 期望值=55, 实际值=%d\n", res)
}
t.Logf("TestAdd执行成功")
}
func TestMultiAll(t *testing.T) {
tests := []struct {
name string
para, expect uint64
}{
{
"n = 3", 3, 6},
{
"n = 4", 4, 24},
{
"n = 5", 5, 120},
{
"n = 7", 7, 5040},
{
"n = 10", 10, 3628801},
}
for _, v := range tests {
t.Run(v.name, func(tt *testing.T) {
real := multi(v.para)
if v.expect != real {
t.Errorf("[%#v] expect = %v, but output = %v\n", v.name, v.expect, real)
}
})
}
}
(3)测试函数文件2
//fiber_test.go
package cal
import (
"strconv"
"testing"
)
func TestFiber(t *testing.T) {
tests := map[int]int{
1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8}
for key, val := range tests {
t.Run("fiber_"+strconv.Itoa(key), func(tt *testing.T) {
real := fiber(key)
if val != real {
t.Errorf("[%#v] expect = %v, but output = %v\n", "fiber_"+strconv.Itoa(key), val, real)
}
})
}
}
2.1.2、测试方法
(1)直接测试所有文件
UnitTest\add_sub> go test -v
=== RUN TestAdd
cal_test.go:12: TestAdd执行成功
--- PASS: TestAdd (0.00s)
=== RUN TestMultiAll
=== RUN TestMultiAll/n_=_3
=== RUN TestMultiAll/n_=_4
=== RUN TestMultiAll/n_=_5
=== RUN TestMultiAll/n_=_7
=== RUN TestMultiAll/n_=_10
=== CONT TestMultiAll
cal_test.go:30: ["n = 10"] expect = 3628801, but output = 3628800
--