go单元测试

接着上一篇中的go module创建项目calc为例,在simplemath包中,是使用在命令行中使用交互式的方式进行测试,现在可以为这几个函数实现单元测试, go test,这个测试工具来自于 Go 官方的 gc 工具链。
运行 go test 命令将执行当前目录下的包的测试代码,它会寻找 *_test.go 文件,并在这些文件中,寻找符合 TestXxx(*testing.T){} 命名的函数和参数(即,接收 *testing.T 参数的函数,命名为 TestXxxXxx 可以是任何不以小写字符开头的名字)。这个测试代码不会影响正常的编译过程,只在执行 go test 时被使用,如果对pytest有过了解,这个就可以轻松使用

编写单元测试

接着新增add_test.gosqrt_test.go两个文件,分别为add.gosqrt.go编写单元测试,目录如下所示,通常测试代码和被测试代码在同一个包中
在这里插入图片描述
其中add_test.go如下

package simplemath

import "testing"

func TestADD(t *testing.T) {
	r := Add(1, 2)
	if r != 3 {
		t.Errorf("Add(1, 2) failed, Got %d, expected 3.", r)
	}
}

sqrt_test.go如下

package simplemath
import "testing"
func TestSqrt(t *testing.T) {
	v := Sqrt(9)
	if v != 3 {
		t.Errorf("Sqrt(9) failed. Got %v, expected 3.", v)
	}
}

在编写单元测试时,需要引入testing包,类似pytest中的pytest包,go中的单元测试标准类型如下:

func TestXXX(t *testing.T) {
    // 测试逻辑
}

运行单元测试

使用goland编译器,选择要执行的单元测试的包,如这里的simplemath,然后痛右键菜单执行,这里和pytest几乎没有差异,因为goland和pycharm也是全家桶中的成员,所以如果之前使用过pytest和pycharm的搭配,这里就很容易上手
在这里插入图片描述
接着可以看到执行输出窗口如下
在这里插入图片描述
当然也可以在test测试文件点击如下所示,点击包名左侧的执行按钮,和上述点击工程目录栏是一样的效果
在这里插入图片描述
对应点击测试函数右侧的执行符号,则执行单个测试函数或者测试类。
我们知道负数无法平方根的,因此这里还要测试下sqrt函数的无效等价类测试

func TestNegativeSqrt(t *testing.T) {
	v := Sqrt(-9)
	if v != 3 {
		t.Errorf("Sqrt(9) failed. Got %v, expected 3.", v)
	}
}

输出如下所示
在这里插入图片描述

这里执行时就会报错,如果执行代码发现的❎,一方面可以使用goland自身的debug,此外还可以使用GDB进行调试,是一个由 GNU 开源组织发布的、Unix/Linux 操作系统下的、基于命令行的、功能强大的程序调试工具,Go 语言编译后的二进制文件支持通过 GDB 进行调试,比如上篇教程通过 go build calc 编译出来的可执行文件 calc,就可以直接用以下命令以调试模式运行

gdb calc

注:Windows 系统不支持该工具,Mac 下可以通过 brew install gdb 命令安装
然后,你就可以通过 GDB 支持的指令以命令行的方式对 Go 代码进行调试了,你可以通过 l 指令查看代码:
在这里插入图片描述

GDB 代码调试
要跳到某一行查看通过 l 传入行数即可:
在这里插入图片描述

GDB 代码调试
要为某一行设置断点可以通过 b 来实现:
在这里插入图片描述

GDB 代码调试
然后通过 run 命令来运行程序,如果是在 Mac 系统上,可能会报下面这个错:
在这里插入图片描述

GDB 代码调试
这是因为 Darwin 内核在你没有特殊权限的情况下,不允许调试其它进程。调试某个进程,意味着你对这个进程有完全的控制权限,所以为了防止被恶意利用,它是默认禁止的。允许 gdb 控制其它进程最好的方法就是用系统信任的证书对它进行签名,对应的解决方法参考这里:https://opensource.apple.com/source/lldb/lldb-69/docs/code-signing.txt(中文对应的解决方式)。

进入下一行可以用 n 指令,打印变量可以用 p 指令传入变量名。。。更多指令使用我就不深入展开了,因为对于新手来说,不推荐使用 GDB 进行代码调试,直接使用 GoLand 更友好,不是吗?如果你想探究 GDB 调试的更多用法,请查看对应的官方文档 Debugging Go Code with GDB

跳过测试

既然同pytest有相似之处,go test也支持skip test,当不满足某个条件时跳过该测试case。

func TestSkip(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test")
	}
	time.Sleep(10 * time.Second)
	// do something
}

这里引用 GO WEB编程中的一段test,使用-short标记来避免一个长时间运行的测试用例,类似pytest中的skip.tag标识。
在这里插入图片描述
在terminal测试包smiplemath中执行go test.输出测试结果,然后接着使用带有tag进行skip测试

go test -v -cover -short

输出如下:

=== RUN   TestADD
--- PASS: TestADD (0.00s)
=== RUN   TestSqrt
--- PASS: TestSqrt (0.00s)
=== RUN   TestNegativeSqrt
    sqrt_test.go:17: Sqrt(9) failed. Got -9223372036854775808, expected 3.
--- FAIL: TestNegativeSqrt (0.00s)
=== RUN   TestSkip
    sqrt_test.go:23: skipping test
--- SKIP: TestSkip (0.00s)
FAIL
coverage: 100.0% of statements
exit status 1
FAIL    calc/simplemath 0.495s

使用-options参数是,最重要的是查阅help

go help test
// go help testflag
        -v
            Verbose output: log all tests as they are run. Also print all
            text from Log and Logf calls even if the test succeeds.

并行测试

或者说是并发测试我理解也是可以的,尤其是在e2e测试中,由于每个case是独立的(前置条件,步骤和预期结果),如果一个case执行时间为2s,则并行执行可以较能发挥出机器的优势,见如下

package simplemath

import (
	"testing"
	"time"
)

func TestAdd1(t *testing.T) {
	sum := Add(1 ,2)
	time.Sleep(1 * time.Second)
	if sum != 3 {
		t.Errorf("Add(1, 2) failed. Got %v, expected 3.", sum)
	}
}

func TestAdd2(t *testing.T) {
	sum := Add(2 ,3)
	time.Sleep(2 * time.Second)
	if sum != 5 {
		t.Errorf("Add(2, 3) failed. Got %v, expected 5.", sum)
	}
}

func TestAdd3(t *testing.T) {
	sum := Add(3 ,4)
	time.Sleep(3 * time.Second)
	if sum != 7 {
		t.Errorf("Add(3, 4) failed. Got %v, expected 7.", sum)
	}
}

输出结果如下所示

=== RUN   TestADD
--- PASS: TestADD (0.00s)
=== RUN   TestAdd1
--- PASS: TestAdd1 (1.00s)
=== RUN   TestAdd2
--- PASS: TestAdd2 (2.00s)
=== RUN   TestAdd3
--- PASS: TestAdd3 (3.00s)
PASS
ok      calc/simplemath 6.144s

这样不算调度时间,整体运行时间 > 6s,先让使用testing.TParallel函数,执行

go test -v -short -parallel 3

基准测试

Go的 testing 包支持两种类型的测试,一种是用于检验程序功能性的功能测试(functional testing),而另一种则是用于**查明任务单元性能**的基准测试(benchmarking)。在上一节学习过如何进行功能测试之后,这一节我们将要学习如何进行基准测试。关于基准测试参考基准测试介绍

跟单元测试一样,基准测试用例也需要放置到以 _test.go 为后缀的文件中,并且每个基准测试函数都需要符合以下格式:

func BenchmarkXxx(*testing.B) { ... }

func BenchmarkExercise(b *testing.B) {
	for i := 0; i < b.N; i++ {
		fmt.Println("testest")
		funcitonModule()
	}
}

循环执行解码函数,以便对其进行b.N 次基准测试.在Go语言中进行基准测试是非常直观的:测试程序要做的就是将被测试的代码执行 b.N 次,以便准确地检测出代码的响应时间,其中 b.N 的值将根据被执行的代码而改变。比如,在上面展示的基准测试例子中,测试程序就将 funcitonModule 函数执行了 b.N 次。

为了运行基准测试用例,用户需要在执行 go test 命令时使用基准测试标志 -bench ,并将一个正则表达式用作该标志的参数,从而标识出自己想要运行的基准测试文件。当我们需要运行目录下的所有基准测试文件时,只需要把点( .) 用作 -bench 标志的参数即可:

go test -v -cover -short –bench .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值