golang testing使用

news/2024/10/18 8:31:46/

testing包服务于自动化测试

基本测试

Table Drvien Test

基于表的测试通过表形式进行测试每种情况的输入和期望输出,从而测试程序的正确性

func TestFib(t *testing.T) {var fibTests = []struct {in       int // inputexpected int // expected result}{{1, 1},{2, 1},{3, 2},{4, 3},{5, 5},{6, 8},{7, 13},}for _, tt := range fibTests {actual := Fib(tt.in)if actual != tt.expected {t.Errorf("Fib(%d) = %d; expected %d", tt.in, actual, tt.expected)}}
}

反馈测试情况接口

  • 跳过测试
    • SkipNow(): 跳过测试
    • Skip(): 跳过测试并输出log
    • Skipf(): 跳过测试并格式化输出log
  • 失败但继续
    • Fail(): 标记测试失败,但继续执行
    • FailNow(): 标记测试失败,不继续执行
    • Error(): 标记测试失败,并输出
    • Errorf(): 标记测试失败,并格式化输出
  • 输出
    • Log(): 输出
    • Logf(): 格式化输出
  • 失败且中断
    • Fatal(): 相当于FailNow() + Log()
    • Fatalf(): 相当于FailNow() + Logf()

Parallel()

Parallel方法表示会和其他带有Parallel方法的测试并行执行

ExampleXXX()

ExampleXXX方法中如果含有Output: 开头的行注释,则会在运行测试期间,将输出和注释中的值相比较

如果是不确定的顺序,则可以以Unordered output: 作为开头

但如果没有这样的注释,这就是一个普通函数,不能被直接运行

压力测试

压力测试方法以func BenchmarkXXX(*testing.B)函数名展现。

函数体格式如下

func BenchmarkHello(b *testing.B) {for i := 0; i < b.N; i++ {// do sth}
}

压力测试会自动调整b.N使得持续足够长时间

重置计时器

如果想要跳过不需要计时的耗时工作,那么可以通过b.ResetTimer()重置计时器

并行测试

如果想并行压力测试,那么可以通过RunParallel实现

func BenchmarkHelloParallel(b *testing.B) {b.RunParallel(func(pb *testing.PB) {// do sth})
}

内存统计

ReportAllocs方法用于打开内存统计功能

输出结果就会变成如下形式

// 方法名		迭代总次数		平均每次迭代时间		平均每次迭代分配字节数		平均每次迭代的内存分配次数
BenchmarkHello        2000000           898 ns/op         368 B/op           9 allocs/op

自定义度量值

ReportMetric(n float64, unit string)汇报自定义度量值

  • 如果度量值是每次迭代的,你应该将其除以 b.N。按照惯例,单位应该以 “/op” 结尾。
  • ReportMetric 会覆盖同一单位的任何先前报告的值。
  • 如果单位是空字符串,或者单位包含任何空格,ReportMetric 会引发 panic。
  • 如果单位是基准测试框架本身通常报告的单位(如 “allocs/op”),ReportMetric 会覆盖该度量值。将 “ns/op” 设置为 0 将禁止该内置度量值。
	testing.Benchmark(func(b *testing.B) {var compares int64for i := 0; i < b.N; i++ {s := []int{5, 4, 3, 2, 1}sort.Slice(s, func(i, j int) bool {compares++return s[i] < s[j]})}// This metric is per-operation, so divide by b.N and// report it as a "/op" unit.b.ReportMetric(float64(compares)/float64(b.N), "compares/op")// This metric is per-time, so divide by b.Elapsed and// report it as a "/ns" unit.b.ReportMetric(float64(compares)/float64(b.Elapsed().Nanoseconds()), "compares/ns")})

子测试

子测试也就是可以在测试中测试,子测试可以共用初始化等公共操作,并可以做父测试执行前的必要操作

func TestSubTest(t *testing.T) {t.Run("sub1", func(t *testing.T) {t.Log("sub1")})t.Run("sub2", func(t *testing.T) {t.Log("sub2")})t.Run("sub3", func(t *testing.T) {t.Log("sub3")})
}

模糊测试

模糊测试方法名为func FuzzXXX(f *testing.F)

func FuzzReverse(f *testing.F) {// 为模糊测试添加用例到种子语料库testcases := []string{"Hello, world", " ", "!12345"}for _, tc := range testcases {f.Add(tc)  // Use f.Add to provide a seed corpus}// 进行模糊测试。对于string类型的参数,将生成随机字符串// 对于本测试中的Reverse方法是可逆的,因此可以通过两次逆行操作来验证其正确性f.Fuzz(func(t *testing.T, orig string) {rev := Reverse(orig)doubleRev := Reverse(rev)if orig != doubleRev {t.Errorf("Before: %q, after: %q", orig, doubleRev)}if utf8.ValidString(orig) && !utf8.ValidString(rev) {t.Errorf("Reverse produced invalid UTF-8 string %q", rev)}})
}

运行模糊测试有go testgo test -fuzz两种方式,前者仅会运行手动添加的用例,而后者则会随机生成数据

值得注意的是如果go test -fuzz执行之后存在运行错误的用例会添加到语料库文件中,那么即使下次执行的是go test也依然会执行语料库文件中的用例

Ref

  1. https://go.dev/doc/tutorial/fuzz
  2. https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter09/09.0.html

http://www.ppmy.cn/news/1457010.html

相关文章

ROS机器人实用技术与常见问题解决

问题速查手册&#xff08;时实更新&#xff09;更加全面丰富的问题手册记录 1.机器人使用GPARTED挂载未分配空间 需要在图型界面下操作&#xff0c;建议使用no machine连接 安装gparted磁盘分区工具, sudo apt-get install gparted -y 启动软件 sudo gparted 点击磁盘/内存…

本机MySQL数据库服务启动了,但是cmd登录不上10061

注意&#xff1a;不建议安装MySQL8&#xff0c;建议直接使用phpstudy中自带的MySQL5.7 错误信息 ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x (10061) 原因 可能是端口号错误。比如修改了my.ini中&#xff0c;或者phpstudy中数据库端口的配置&#xff0c;…

2024年荆州中级工程师报名开始了吗?

2024年荆州中级工程师职称报名已经开始了 2024年荆州中级职称报名时间&#xff1a; &#xff08;一&#xff09;网上报名时间&#xff1a; 4月26日9时至5月10日16时。超过时间将不能操作。 &#xff08;二&#xff09;网上缴费时间&#xff1a; 4月26日9时至5月10日24时 网上…

QT--2

Qt界面设计 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//窗口相关设置this->resize(680,520);this->setFixedSize(680,520);this->setWindowTitle("Tim");this->setWindowFla…

免收隔夜费的外汇平台特点与选择

外汇交易是一种全球范围内的投资活动&#xff0c;参与者包括银行、机构投资者、交易商和个人交易者。在外汇交易中&#xff0c;隔夜费&#xff08;也称为掉期费或展期费&#xff09;是当持仓过夜时&#xff0c;因货币对利率差异而产生的费用。这种费用对一些交易者&#xff0c;…

【无标题】程序设计和c语言-谭浩强配套(适合专升本)

一晃大半年没更新了&#xff0c;一直在备考&#xff0c;想着这几天把前段时间学的c语言给大家分享一下&#xff0c;在此做了一个专栏&#xff0c;有需要的小伙伴可私信获取。 说明&#xff1a;本专栏所有内容皆适合专升本复习资料&#xff0c;本人手上也有日常刷题整理的错题以…

C语言—控制语句

控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1&#xff1b; } else { 语句块2&#xff1b; } 执行顺序&#xff1a; 如果表达式判断成立&#xff08;即表达式为真&#xff09;&#xff0c;则执行语句块…

JAVA面试常见面试问题01

1、队列系列 1.1、选型 ActiveMq ⼩规模场景&#xff0c;有较低概率丢失消息&#xff0c;官方社区维护少 RabbitMq ⼩规模场景&#xff0c;吞吐量⽐较低&#xff0c;消息积累会严重影响性能 RocketMQ ⼩规模场景&#xff0c;官⽅⽂档和周边⽣态还不够成熟 Kafka 大规模场景…