[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`來查看測試覆蓋率。

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指南
- 小操作