[TOC]
## **1.Go测试**
Go语言中的测试依赖`go test`命名。在包目录内,所有以`_test.go`为后缀名的源代码文件都是`go test`测试的一部分,不会被`go build`编译到最终的可执行文件中。
在`*_test.go`文件中有三种类型的函数、单元测试函数、基准测试函数和示例函数。
| 类型 |格式 |作用 |
| --- | --- |--- |
| 测试函数 | 函数名前缀为Test | 测试程序的一些逻辑行为是否正确|
| 基准函数 | 函数名前缀为Benchmark |测试函数的性能 |
| 示例函数 | 函数名前缀为Example | 为文档提供示例文档|
`go test`命令会遍历所有的`*_test.go`文件中符合上述命名规则的函数,
并生成一个临时的main包用于调用相应的测试函数,
然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。
~~~go
func TestSplit(t *testing.T) { // 测试函数名必须以Test开头,必须接收一个*testing.T类型参数
got := Split("a:b:c", ":") // 程序输出的结果
want := []string{"a", "b", "c"} // 期望的结果
if !reflect.DeepEqual(want, got) { // 因为slice不能比较直接,借助反射包中的方法比较
t.Errorf("expected:%v, got:%v", want, got) // 测试失败输出错误提示
}
}
func TestMoreSplit(t *testing.T) {
got := Split("abcd", "bc")
want := []string{"a", "d"}
if !reflect.DeepEqual(want, got) {
t.Errorf("expected:%v, got:%v", want, got)
}
}
~~~
```
go test // 执行 test文件
go test -v // 查看测试函数名称和运行时间
go test -v -run="more" //-run参数对应正则表达式。
```
## **2.单元测试函数**
每个测试函数必须导入 `testing` 包,测试函数的基本格式(签名)如下:
~~~go
func TestName(t *testing.T){
// ...
}
~~~
测试函数的命名必须以`Test`开头。
```
// 其中 t 用于报告测试失败和附加的日志信息。
func TestAdd(t *testing.T){ ... }
func TestSum(t *testing.T){ ... }
func TestLog(t *testing.T){ ... }
```
`go test`:在某一路径下执行该命令,会运行该目录下所有*_test.go文件。
`go test -v`:输出完整的测试结果,能更好地在输出结果中看到每个测试用例执行情况。
`go test -run=reg -v`:`-run`参数对应一个正则,只有函数名匹配上的测试函数才会被执行。
## **3.跳过某些测试**
为了节省时间支持在单元测试时跳过某些耗时的测试用例。
```
func TestTimeConsuming(t *testing.T) {
if testing.Short() {
t.Skip("short模式下会跳过该测试用例")
}
...
}
```
当执行`go test -short`时就不会执行上面的`TestTimeConsuming`测试用例。
## **4.子测试**
在Go1.7+新增了子测试,支持在测试函数中使用`t.Run`执行一组测试用例,这样就不需要为不同的测试数据定义多个测试函数了。
~~~go
func TestXXX(t *testing.T){
t.Run("case1", func(t *testing.T){...})
t.Run("case2", func(t *testing.T){...})
t.Run("case3", func(t *testing.T){...})
}
~~~
## **5.表格驱动测试**
表格驱动测试不是工具、包或其他任何东西,它只是编写更清晰测试的一种方式和视角。
表格驱动测试可以涵盖很多方面:表格里的每一个条目都是一个完整的测试用例,包含输入和预期结果,有时还包含测试名称等附加信息,以便于输出易于阅读。
使用表格驱动测试能够很方便的维护多个测试用例,避免在编写单元测试时频繁的复制粘贴。
## **6.并行测试**
在单元测试过程中使用并行测试,通过添加`t.Parallel()`来实现。
## **7.使用工具生成测试代码**
gotests可以快速生成测试文件。
```
go get -u github.com/cweill/gotests/...
gotests -all -w split.go
```
## **8.测试覆盖率**
测试覆盖率指代码被测试套件覆盖的百分比。
Go提供内置功能来检查你的代码覆盖率,`go test -cover`来查看测试覆盖率。
![](https://img.kancloud.cn/8c/7a/8c7a13f6fcf2f549791b9f998257ba4a_578x123.png)
Go还提供`-coverprofile`参数,用来将覆盖率相关的记录信息输出到一个文件。
```
go test -cover -coverprofile=c.out
```
然后可以执行`go tool cover -html=c.out`,使用`cover`工具来处理生成的记录信息,该命令会打开本地的浏览器窗口生成一个HTML报告。
## **9.testify/assert**
testify是一个流行的Go单元测试工具包,其中使用最多的功能就是它提供的断言工具——`testify/assert`或`testify/require`。
**安装**
```
go get github.com/stretchr/testify
```
在写单元测试时,通常需要使用断言来校验测试结果,由于Go官方没有提供断言,就会写很多if...eles语句。而`testify/assert`为我们提供了很多常用的断言函数,并且能够输出友好、易于阅读的错误描述信息。
```
t.Run(tt.name, func(t *testing.T) { // 使用t.Run()执行子测试
got := Split(tt.input, tt.sep)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("expected:%#v, got:%#v", tt.want, got)
}
})
// 简化
t.Run(tt.name, func(t *testing.T) { // 使用t.Run()执行子测试
got := Split(tt.input, tt.sep)
assert.Equal(t, got, tt.want) // 使用assert提供的断言函数
})
```
当有多个断言语句时,可以使用`assert := assert.New(t)`创建一个assert对象,它拥有前面所有的断言方法,只是不需要再传入`Testing.T`参数了。
- Golang
- 基础知识
- 基本数据类型
- 运算符
- 变量&常量
- 流程控制
- 数组
- 切片
- string操作
- Map及实现原理
- Go其他
- CLI命令
- Golang内置类型和函数
- init函数和main函数
- 网络编程
- 互联网协议
- socket编程
- 单元测试
- 并发编程
- channel
- 优雅地关闭channel
- Mutex
- GMP原理与调度
- Go Web
- HTTP Server
- gin框架
- 快速入门
- HTML渲染
- JSONP
- Multipart/Urlencoded绑定
- PureJSON
- gin路由
- beego框架
- Bee工具安装
- 配置模块
- Web模块
- 路由
- 数据操作
- Go操作Mysql数据库
- Go操作redis
- mongo-driver
- sqlx库
- 操作etcd
- msgpack
- 网络爬虫
- 获取页面
- 标准库
- IO操作
- 文件操作
- fmt
- 格式化输出
- flag
- log
- time
- strconv
- template
- os
- sync.Mutex
- Context
- 第三方库
- zap库
- viper
- validator参数校验
- GORM
- 基础
- CRUD接口
- INI
- GoFrame
- 快速开始
- 微服务
- go-kit
- gRPC
- Protocol Buffers 语法指南
- go-zero
- 相关名词解释
- 数据结构和算法
- 基础知识
- 链表
- Golang GUI
- fyne基础
- 显示时间
- RabbitMQ-Go
- centos7 安装rabbitmq-server
- RabbitMQ介绍
- 工作队列
- Go设计模式
- 设计模式的分类
- 简单工厂模式
- golang自举编译
- 了解sync.Once
- 知识碎片
- 常见问题
- 开源项目
- Python
- Anaconda
- 介绍、使用教程
- Python基础知识
- Python之禅
- 变量和类型
- 流程控制
- Python运维
- Python内置工具
- 命令行工具
- 包管理工具pip
- 小爬虫笔记
- I/O操作
- requests库
- requests基本使用
- BeautifulSoup库
- BeautifulSoup基本使用
- Scrapy框架
- 数据可视化
- Django
- Django起步
- OpenCV
- OpenCV入门
- 前端
- HTML
- CSS
- CSS权重计算
- Javascript
- 基础
- JS基础知识
- 监听事件
- 字符串操作
- 数组操作
- 输入输出
- 定时器
- 样式操作
- 获取url参数
- Typescript
- Pick 与 Omit TS内置类型
- Vue.js
- Vue.js介绍
- Vue.js基础
- Vue指令
- v-model
- v-for
- 指令修饰符
- Q&A
- 命令
- Vue3
- node.js
- node.js基础
- npm遇到的问题
- 相关工具安装
- nvm使用教程
- 工程化webpack
- Linux
- Linux基础
- 符号链接
- Shell
- 脚本执行方式
- 数据的输入输出
- 脚本执行中的问题
- tcpdump
- 正则表达式
- Elasticsearch
- Docker
- Docker的基础概念与操作
- Docker 安装
- 容器技术原理
- Docker核心概念
- Docker基本操作
- 镜像相关操作
- 容器相关操作
- 镜像加速器
- Dockerfile
- COPY复制文件
- Docker所遇问题
- ansible
- ansible入门
- k8s
- 安装工具
- kubectl
- Git
- gitlab
- gitlab备份与恢复
- gitlab基本使用
- git使用
- git常用命令
- git提交问题
- git提交规范
- 数据库
- MySQL
- MySQL介绍
- mariadb安装
- 主主复制
- 数据库问题集结
- 开启binlog
- MySQL常用命令
- SQL总结
- MySQL性能优化系列
- 第一章 初始化安装和简单安全加固
- 第二章 认识performance_schema
- 第三章 MySQL体系结构
- MySQL配置模板
- Redis
- Redis简单使用
- Redis常见问题
- Redis集群
- Redis Cluster概述
- 数据分布
- 搭建集群
- MongoDB
- mongodb分片
- MongoDB分片集群设置密码验证
- TiDB
- 单机模拟部署生产环境集群
- 服务器
- CentOS
- 配置阿里云的yum源和epel源
- centos7 实现NFS文件共享
- rsync
- centos7 源码编译rsync
- rsync实现文件同步
- 添加删除swap分区
- 清除buff/cache
- 配置ntp时间同步
- centos7安装pip
- centos7虚拟机启动报xfs错误
- centos7常用命令
- centos7安装mysql
- centos7安装python3.x
- centos7升级gcc、g++
- centos7安装nginx
- centos7部署Nexus
- centos7离线安装python3
- centos7.6编译mariadb10.5.22
- CentOS8
- 银河麒麟V4
- nginx编译
- 银河麒麟V10_x86
- 安装VNC
- 单用户模式
- UOS
- 配置本地apt源
- apt安装vnc-server
- UOS单用户模式
- UOS创建自启动脚本
- 源码编译
- oniguruma编译
- Proxmox VE
- PVE基本使用
- PVE故障
- KVM
- KVM相关命令
- 银河麒麟V10_x86安装kvm
- UOS_arm64安装kvm
- yum、rpm、apt
- dpkg、apt-get、yum和rpm的区别
- rpm打包
- yum相关问题
- 内建银河麒麟的apt源
- 其他软件
- JuiceFS
- nacos
- 常见命令
- 硬盘分区
- Linux常见问题
- 测试
- sysbench
- 其他
- Cloc代码统计工具
- onlyoffice 在线文档编辑
- onlyoffice添加中文字体
- 遇到的问题
- 网络通信协议
- 部署相关记录
- Vmware workstation虚拟机迁移到PVE指南
- 小操作