最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go單元測(cè)試工具gomonkey的使用

 更新時(shí)間:2022年06月23日 10:11:34   作者:banjming  
本文主要介紹了Go單元測(cè)試工具gomonkey的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Go 單元測(cè)試工具

測(cè)試分為4個(gè)層次

  • 單元測(cè)試:對(duì)代碼進(jìn)行測(cè)試
  • 集成測(cè)試:對(duì)一個(gè)服務(wù)的接口測(cè)試
  • 端到端測(cè)試(鏈路測(cè)試):從一個(gè)鏈路的入口輸入測(cè)試用例,驗(yàn)證輸出的系統(tǒng)的結(jié)果
  • UI測(cè)試

常犯的錯(cuò)誤:

  • 沒(méi)有斷言。沒(méi)有斷言的單測(cè)是沒(méi)有靈魂的。

單測(cè)的特征:

  • A:(Automatic,自動(dòng)化):?jiǎn)卧獪y(cè)試應(yīng)該是全自動(dòng)執(zhí)行的,并且非交互式的
  • I:(Independent,獨(dú)立性):為了保證單元測(cè)試穩(wěn)定可靠且便于維護(hù),單元測(cè)試用例之間決不能互相調(diào)用,也不能依賴(lài)執(zhí)行的先后次序。
  • R:(Repeatable,可重復(fù)):?jiǎn)卧獪y(cè)試通常會(huì)被放到持續(xù)集成中,每次有代碼 check in 時(shí)單元測(cè)試都會(huì)被執(zhí)行。

單測(cè)

代碼 bug 總是在所難免, 越早發(fā)現(xiàn)問(wèn)題解決成本越低, 單測(cè)可以盡早的暴露錯(cuò)誤。提高代碼之路,使得項(xiàng)目更高質(zhì)量的交付。 起碼有三個(gè)優(yōu)點(diǎn):

  • 提高代碼質(zhì)量

編寫(xiě)單測(cè)是自測(cè)的一部分,編寫(xiě)新代碼時(shí)增加相應(yīng)的單測(cè),可以幫助我們發(fā)現(xiàn)大部分的bug,有助于減少聯(lián)調(diào)時(shí)的調(diào)整,提高聯(lián)調(diào)效率。

  • 花更少的時(shí)間進(jìn)行功能測(cè)試

功能測(cè)試成本相對(duì)較高,因?yàn)榻?jīng)常需要執(zhí)行一系列操作以驗(yàn)證結(jié)果是否符合預(yù)期。如果問(wèn)題如果發(fā)現(xiàn)了問(wèn)題,溝通和復(fù)測(cè)往往要花費(fèi)很多的時(shí)間。

  • 花更少的時(shí)間進(jìn)行回歸測(cè)試

回歸測(cè)試是為了避免在對(duì)應(yīng)用程序進(jìn)行更改時(shí)引入bug。測(cè)試人員不僅要測(cè)試他們的新特性,還要測(cè)試以前存在的特性,以驗(yàn)證之前實(shí)現(xiàn)的特性是否仍然像預(yù)期的那樣運(yùn)行。 通過(guò)單元測(cè)試,可以在每次構(gòu)建之后,重新運(yùn)行整個(gè)測(cè)試流程,以確保新代碼不會(huì)破壞已有功能

  • 測(cè)試異常場(chǎng)景

一些異常的場(chǎng)景QA不好構(gòu)造,比如并發(fā)出款是否資金安全,事務(wù)異常相關(guān)測(cè)試等等。而問(wèn)題經(jīng)常出現(xiàn)在這些異常的場(chǎng)景,可能引發(fā)線(xiàn)上問(wèn)題甚至是事故。 而單元測(cè)試可通過(guò)mock的方式方便的模擬各種異常場(chǎng)景。

Go 單元測(cè)試工具

gomonkey

引入 gomonkey 有如下好處:

  • 隔離被測(cè)代碼
  • 加速執(zhí)行測(cè)試
  • 使執(zhí)行變得確定
  • 模擬特殊情況

功能列表

  • 支持為一個(gè)函數(shù)打一個(gè)樁
  • 支持為一個(gè)函數(shù)打一個(gè)特定的樁序列
  • 支持為一個(gè)成員方法打一個(gè)樁
  • 支持為一個(gè)成員方法打一個(gè)特定的樁序列
  • 支持為一個(gè)函數(shù)變量打一個(gè)樁
  • 支持為一個(gè)函數(shù)變量打一個(gè)特定的樁序列
  • 支持為一個(gè)接口打樁
  • 支持為一個(gè)接口打一個(gè)特定的樁序列
  • 支持為一個(gè)全局變量打一個(gè)樁

函數(shù)打樁, 對(duì)變量的 mock 實(shí)現(xiàn)原理跟 gostub 一樣都是通過(guò) reflect 包實(shí)現(xiàn)的。除了 mock 變量,gomonkey 還可以直接 mock 導(dǎo)出函數(shù)/方法、mock 代碼所在包的非導(dǎo)出函數(shù)

Go monkey Permission Denied 解決方案:https://github.com/eisenxp/macos-golink-wrapper

mv $GOROOT/pkg/tool/darwin_amd64/link $GOROOT/pkg/tool/darwin_amd64/original_link
cp https://github.com/eisenxp/macos-golink-wrapper/link $GOROOT/pkg/tool/darwin_amd64/link

下載文件,然后再 cp

wget https://raw.githubusercontent.com/eisenxp/macos-golink-wrapper/main/link  

gomonkey 提供了如下 mock 方法:

  • ApplyGlobalVar(target, double interface{}):使用 reflect 包,將 target 的值修改為 double
  • ApplyFuncVar(target, double interface{}):檢查 target 是否為指針類(lèi)型,與 double 函數(shù)聲明是否相同,最后調(diào)用 ApplyGlobalVar
  • ApplyFunc(target, double interface{}):修改 target 的機(jī)器指令,跳轉(zhuǎn)到 double 執(zhí)行
  • ApplyMethod(target reflect.Type, methodName string, double interface{}):修改 method 的機(jī)器指令,跳轉(zhuǎn)到 double 執(zhí)行
  • ApplyFuncSeq(target interface{}, outputs []OutputCell):修改 target 的機(jī)器指令,跳轉(zhuǎn)到 gomonkey 生成的一個(gè)函數(shù)執(zhí)行,每次調(diào)用會(huì)順序從 outputs 取出一個(gè)值返回
  • ApplyMethodSeq(target reflect.Type, methodName string, outputs []OutputCell):修改 target 的機(jī)器指令,跳轉(zhuǎn)到 gomonkey 生成的一個(gè)方法執(zhí)行,每次調(diào)用會(huì)順序從 outputs 取出一個(gè)值返回
  • ApplyFuncVarSeq(target interface{}, outputs []OutputCell):gomonkey 生成一個(gè)函數(shù)順序返回 outputs 中的值,調(diào)用 ApplyGlobalVar

gomonkey 打樁失敗的可能原因

  • gomonkey 不是并發(fā)安全的。如果有多協(xié)程并發(fā)對(duì)同一個(gè)目標(biāo)的打樁的情況,則需要將之前的協(xié)程先優(yōu)雅退出。
  • 打樁目標(biāo)為內(nèi)聯(lián)的函數(shù)或成員方法。可通過(guò)命令行參數(shù) -gcflags=-l (go1.10 版本之前)或-gcflags=all=-l(go1.10 版本及之后)關(guān)閉內(nèi)聯(lián)優(yōu)化。
  • gomonkey 對(duì)于私有成員方法的打樁失敗。go1.6 版本的反射機(jī)制支持私有成員方法的查詢(xún),而 go1.7 及之后的版本卻不支持,所以當(dāng)用戶(hù)使用 go1.7 及之后的版本時(shí),gomonkey 對(duì)于私有成員方法的打樁會(huì)觸發(fā)異常。

goconvey

為全局變量打一個(gè)樁

package unittest

import (
	"testing"

	"github.com/agiledragon/gomonkey"
	"github.com/smartystreets/goconvey/convey"
)

var num = 10 //全局變量

func TestApplyGlobalVar(t *testing.T) {
	convey.Convey("TestApplyGlobalVar", t, func() {
		convey.Convey("change", func() {
			patches := gomonkey.ApplyGlobalVar(&num, 150)
			defer patches.Reset()
			convey.So(num, convey.ShouldEqual, 150)
		})

		convey.Convey("recover", func() {
			convey.So(num, convey.ShouldEqual, 10)
		})
	})
}

執(zhí)行結(jié)果:

=== RUN   TestApplyGlobalVar
..
2 total assertions

--- PASS: TestApplyGlobalVar (0.00s)
PASS

為一個(gè)函數(shù)打樁

func networkCompute(a, b int) (int, error) {
	// do something in remote computer
	c := a + b

	return c, nil
}

func Compute(a, b int) (int, error) {
	sum, err := networkCompute(a, b)
	return sum, err
}

func TestFunc(t *testing.T) {
	// mock 了 networkCompute(),返回了計(jì)算結(jié)果2
	patches := gomonkey.ApplyFunc(networkCompute, func(a, b int) (int, error) {
		return 2, nil
	})

	defer patches.Reset()

	sum, err := Compute(1, 2)
	println("expected %v, got %v", 2, sum)
	if sum != 2 || err != nil {
		t.Errorf("expected %v, got %v", 2, sum)
	}
}

結(jié)果:

=== RUN   TestFunc
expected %v, got %v 2 3
    mock_func_test.go:91: expected 2, got 3
--- FAIL: TestFunc (0.00s)

FAIL

可以看到上面的結(jié)果,執(zhí)行時(shí)失敗的,mock 沒(méi)有成功。

有時(shí)會(huì)遇到mock失效的情況,這個(gè)問(wèn)題一般是內(nèi)聯(lián)導(dǎo)致的。

什么是內(nèi)聯(lián)?

為了減少函數(shù)調(diào)用時(shí)的堆棧等開(kāi)銷(xiāo),對(duì)于簡(jiǎn)短的函數(shù),會(huì)在編譯時(shí),直接內(nèi)嵌調(diào)用的代碼。

我們禁用下內(nèi)聯(lián),然后執(zhí)行, go test -v -gcflags=-l mock_func_test.go

執(zhí)行結(jié)果:

=== RUN   TestFunc
expected %v, got %v 2 2
--- PASS: TestFunc (0.00s)
PASS

對(duì)于 go 1.10以下版本,可使用-gcflags=-l禁用內(nèi)聯(lián),對(duì)于go 1.10及以上版本,可以使用-gcflags=all=-l。但目前使用下來(lái),都可以。 關(guān)于gcflags的用法,可以使用 go tool compile --help 查看 gcflags 各參數(shù)含義

到此這篇關(guān)于Go單元測(cè)試工具gomonkey的使用的文章就介紹到這了,更多相關(guān)Go gomonkey內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang模擬TCP粘包和拆包

    golang模擬TCP粘包和拆包

    粘包是指在發(fā)送多個(gè)小的數(shù)據(jù)包時(shí),接收端會(huì)將這些數(shù)據(jù)包合并成一個(gè)數(shù)據(jù)包接收,拆包是指發(fā)送的數(shù)據(jù)包在傳輸過(guò)程中被分割成多個(gè)小包,下面我們來(lái)看看go如何模擬TCP粘包和拆包吧
    2024-12-12
  • Golang連接池的幾種實(shí)現(xiàn)案例小結(jié)

    Golang連接池的幾種實(shí)現(xiàn)案例小結(jié)

    這篇文章主要介紹了Golang連接池的幾種實(shí)現(xiàn)案例小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Go pprof內(nèi)存指標(biāo)含義備忘錄及案例分析

    Go pprof內(nèi)存指標(biāo)含義備忘錄及案例分析

    這篇文章主要介紹了Go pprof內(nèi)存指標(biāo)含義備忘錄問(wèn)題,小編特此把問(wèn)題及案例分享到腳本之家平臺(tái)供大家學(xué)習(xí),需要的朋友可以參考下
    2020-03-03
  • go語(yǔ)言實(shí)現(xiàn)LRU緩存的示例代碼

    go語(yǔ)言實(shí)現(xiàn)LRU緩存的示例代碼

    LRU是一種常見(jiàn)的緩存淘汰策略,用于管理緩存中的數(shù)據(jù),本文主要介紹了go語(yǔ)言實(shí)現(xiàn)LRU緩存的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • Go語(yǔ)言并發(fā)控制之semaphore的原理與使用

    Go語(yǔ)言并發(fā)控制之semaphore的原理與使用

    這篇文章主要為大家詳細(xì)介紹了Go官方庫(kù)x中提供的擴(kuò)展并發(fā)原語(yǔ)?semaphore,譯為“信號(hào)量”,文中介紹了它的原理與使用,需要的可以了解下
    2025-02-02
  • Go?跨域中間件解決CORS問(wèn)題

    Go?跨域中間件解決CORS問(wèn)題

    跨域問(wèn)題CORS是前端開(kāi)發(fā)人員經(jīng)常遇到的問(wèn)題,本文主要介紹了Go?跨域中間件解決CORS問(wèn)題,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • Golang?Configor配置文件工具的使用詳解

    Golang?Configor配置文件工具的使用詳解

    Configor是一個(gè)支持?yaml、json、toml、shell?的配置文件工具,這篇文中主要為大家詳細(xì)介紹了Configor的具體使用,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-08-08
  • Go語(yǔ)言運(yùn)算符案例講解

    Go語(yǔ)言運(yùn)算符案例講解

    這篇文章主要介紹了Go語(yǔ)言運(yùn)算符案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Go語(yǔ)言的互斥鎖的詳細(xì)使用

    Go語(yǔ)言的互斥鎖的詳細(xì)使用

    本文主要介紹了Go語(yǔ)言的互斥鎖的詳細(xì)使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 一文掌握Golang模糊測(cè)試

    一文掌握Golang模糊測(cè)試

    本文主要介紹了一文掌握Golang模糊測(cè)試,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

常山县| 弥勒县| 敦煌市| 来宾市| 涞水县| 于都县| 高安市| 广汉市| 鹤山市| 平度市| 宁陵县| 青田县| 永清县| 晋中市| 阿瓦提县| 获嘉县| 宿松县| 潍坊市| 宣城市| 金湖县| 大埔区| 边坝县| 揭东县| 平原县| 遵化市| 徐闻县| 镇沅| 合水县| 平湖市| 称多县| 开平市| 阳城县| 沙坪坝区| 平南县| 于田县| 福建省| 广元市| 子长县| 东平县| 琼结县| 耿马|