Go單元測(cè)試工具gomonkey的使用_第1頁(yè)
Go單元測(cè)試工具gomonkey的使用_第2頁(yè)
Go單元測(cè)試工具gomonkey的使用_第3頁(yè)
Go單元測(cè)試工具gomonkey的使用_第4頁(yè)
Go單元測(cè)試工具gomonkey的使用_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第Go單元測(cè)試工具gomonkey的使用目錄Go單元測(cè)試工具單測(cè)Go單元測(cè)試工具gomonkeygomonkey打樁失敗的可能原因goconvey為全局變量打一個(gè)樁為一個(gè)函數(shù)打樁什么是內(nèi)聯(lián)?

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)用,也不能依賴執(zhí)行的先后次序。R:(Repeatable,可重復(fù)):?jiǎn)卧獪y(cè)試通常會(huì)被放到持續(xù)集成中,每次有代碼checkin時(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ā)線上問(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ù)

GomonkeyPermissionDenied解決方案:/eisenxp/macos-golink-wrapper

mv$GOROOT/pkg/tool/darwin_amd64/link$GOROOT/pkg/tool/darwin_amd64/original_link

cp/eisenxp/macos-golink-wrapper/link$GOROOT/pkg/tool/darwin_amd64/link

下載文件,然后再cp

wget/eisenxp/macos-golink-wrapper/main/link

gomonkey提供了如下mock方法:

ApplyGlobalVar(target,doubleinterface{}):使用reflect包,將target的值修改為doubleApplyFuncVar(target,doubleinterface{}):檢查target是否為指針類型,與double函數(shù)聲明是否相同,最后調(diào)用ApplyGlobalVarApplyFunc(target,doubleinterface{}):修改target的機(jī)器指令,跳轉(zhuǎn)到double執(zhí)行ApplyMethod(targetreflect.Type,methodNamestring,doubleinterface{}):修改method的機(jī)器指令,跳轉(zhuǎn)到double執(zhí)行ApplyFuncSeq(targetinterface{},outputs[]OutputCell):修改target的機(jī)器指令,跳轉(zhuǎn)到gomonkey生成的一個(gè)函數(shù)執(zhí)行,每次調(diào)用會(huì)順序從outputs取出一個(gè)值返回ApplyMethodSeq(targetreflect.Type,methodNamestring,outputs[]OutputCell):修改target的機(jī)器指令,跳轉(zhuǎn)到gomonkey生成的一個(gè)方法執(zhí)行,每次調(diào)用會(huì)順序從outputs取出一個(gè)值返回ApplyFuncVarSeq(targetinterface{},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ī)制支持私有成員方法的查詢,而go1.7及之后的版本卻不支持,所以當(dāng)用戶使用go1.7及之后的版本時(shí),gomonkey對(duì)于私有成員方法的打樁會(huì)觸發(fā)異常。

goconvey

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

packageunittest

import(

"testing"

"/agiledragon/gomonkey"

"/smartystreets/goconvey/convey"

varnum=10//全局變量

funcTestApplyGlobalVar(t*testing.T){

convey.Convey("TestApplyGlobalVar",t,func(){

convey.Convey("change",func(){

patches:=gomonkey.ApplyGlobalVar(num,150)

deferpatches.Reset()

convey.So(num,convey.ShouldEqual,150)

convey.Convey("recover",func(){

convey.So(num,convey.ShouldEqual,10)

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

===RUNTestApplyGlobalVar

..

2totalassertions

---PASS:TestApplyGlobalVar(0.00s)

PASS

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

funcnetworkCompute(a,bint)(int,error){

//dosomethinginremotecomputer

c:=a+b

returnc,nil

funcCompute(a,bint)(int,error){

sum,err:=networkCompute(a,b)

returnsum,err

funcTestFunc(t*testing.T){

//mock了networkCompute(),返回了計(jì)算結(jié)果2

patches:=gomonkey.ApplyFunc(networkCompute,func(a,bint)(int,error){

return2,nil

deferpatches.Reset()

sum,err:=Compute(1,2)

println("expected%v,got%v",2,sum)

ifsum!=2||err!=nil{

t.Errorf("expected%v,got%v",2,sum)

結(jié)果:

===RUNTestFunc

expected%v,got%v23

mock_func_test.go:91:expected2,got3

---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)銷,對(duì)于簡(jiǎn)短的函數(shù),會(huì)在編譯時(shí),直接內(nèi)嵌調(diào)用的代碼。

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

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

===RUNTestFun

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論