批里批里 (゜-゜)つ🍺 干杯~|

七つ一旋桜

园龄:4年2个月粉丝:6关注:3

Day2 golang測試的基礎使用 | 青训营笔记

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

單元測試

基礎使用

  1. 所有測試文件的文件名以_test.go結尾
  2. 測試函數的名稱格式爲func TestXxx(*testing.T)
  3. 初始化的邏輯可以放到TestMain中 TestMain的聲明方式如下
   func TestMain(m *testing.M) {
   //測試前進行初始化工作
   code := m.Run()
   //測試後釋放資源
   os.Exit(code)
   }

一個標準測單元測試函數案例如下

func Test1(t *testing.T) {
}

如果要在單元測試中輸出一些日誌的話不能使用fmt下的包,而是使用t.Log()函數 如果想要輸出錯誤信息的話需要使用t.Errorf()函數

在這裏,我推薦使用testify庫簡化單元測試的開發過程 這個庫封裝了大量常用的測試邏輯,只需要調用函數就可以省掉大量的if err != nil的代碼 案例如下

package main

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func Test1(t *testing.T) {
	t.Run("equals case", func(t *testing.T) {
		num := 3
		assert.Equal(t, 3, num)
	})
	t.Run("not equals case", func(t *testing.T) {
		num := 0
		assert.NotEqual(t, 3, num)
	})
}

在以上這個案例中測試了兩個case,第一個case中要比較獲取的值與預期相等的情況,第二個case中測試了獲取值與預期值不相等的情況

測試覆蓋率

在代碼測試中需要預想代碼的測試是否所有代碼都被測試到了,如果有代碼沒被測試到,那麼這部分代碼可能就是不安全的 一般業務中的代碼的覆蓋率可以達到50%-60%,比較高的覆蓋率可以達到80% 使函數的職責單一可以提高測試的覆蓋率

怎麼獲取代碼測試的覆蓋率? 測試代碼時添加--cover參數即可 例如 go test xxx_test.go xxx.go --cover

mock測試

爲了保證測試時能夠保證冪等性和穩定性(實際業務測試中會須要得測試情況),需要進行mock測試

mock測試可以使用猴子打樁,對於猴子打樁,可以參考這篇文章 打樁簡單地來說就是運行時使用一個函數替換另一個函數進行測試

例如我們定義了一個函數ReadFirstLine,這個函數的作用是獲取某一個文件,這個測試場景下,那個文件隨時都有可能在測試前被修改,而文件被修改之後,可能會對測試結果造成影響,因此,需要對這個函數的執行結果進行特定 這裏掘金課推薦了一個猴子打樁庫monkey 這個庫利用運行時反射動態修改函數的函數體來實現函數打樁 打樁用法如下 monkey.Patch(原函數, 打樁函數) 打完樁後要記得恢復函數的樁 monkey.Unpatch(需要被恢復的函數的函數名)

例如這個例子

package main

import (
	"bou.ke/monkey"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestProcessFirstLineWithMock(t *testing.T) {
	monkey.Patch(ReadFirstLine, func() string {
		return "line110"
	})
	defer monkey.Unpatch(ReadFirstLine)
	line := ProcessFirstLine() // 這個函數會調用ReadFirstLine
	assert.Equal(t, "line000", line)
}

這裏我推薦另一個猴子打樁庫'gomonkey' 這個庫在實際業務開發中使用起來會比掘金課使用的那個庫更加簡單一些 對於課程中的那個案例,使用gomonkey的代碼如下

func TestProcessFirstLineWithMock2(t *testing.T) {  
 convey.Convey("test", t, func() {  
  patch := gomonkey.ApplyFunc(ReadFirstLine, func() string {  
   return "line110"  
  })  
  defer patch.Reset()  
  line := ProcessFirstLine()  
  assert.Equal(t, "line000", line)  
 })
 }

其中的gomonkey.ApplyFuncmonkey.Patch函數的作用一樣,就是給函數進行打樁 然後下面的patch.Reset函數就是把打過樁的函數恢復的函數 這個庫詳細的可以去參考官方的代碼樣例,對於頻繁使用打樁的測試場景,gomonkey的代碼會比monkey使用起來簡單得多

基準測試

基準測試可以測試出程序的性能以及對cpu的損耗 基準測試的函數名都以Benchmark開頭 一個普通的基準測試函數聲明如下

func BenchmarkXxx(b *tesing.B) {
}

在測試執行之前需要調用函數b.ResetTimer()來重置計時器,以便防止數據初始化的時間影響到測試結果

輸入命令go test -bench=.就可以開始進行並行測試

基準測試同時支持串行測試和並行測試

package main

import "testing"

// 串行基準測試
func BenchmarkSelect(b *testing.B) {
	初始化函數()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		被測試的函數()
	}
}

// 並行基準測試
func BenchmarkSelectParallel(b *testing.B) {
	初始化函數()
	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			被測試的函數()
		}
	})
}

進行並行測試的過程中如果需要使用隨機數可以使用fastrand包下的函數,因爲rand包下的函數在併發場景下會有較大的性能影響,不過需要注意的事fastrand包實現的隨機數比起rand的隨機數不是太隨機

本文作者:七つ一旋桜

本文链接:https://www.cnblogs.com/poifa/p/17716924.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   七つ一旋桜  阅读(10)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起