主要介绍了Go单元测试工具gomonkey的使用,通过示例代码非常详细的介绍,对大家的学习或者工作有一定的参考价值。有需要的朋友下面和边肖一起学习。
目录
Go单元测试工具Single Test Go单元测试工具gomonkeygomonkey桩失败的可能原因goconvey全局变量的桩和函数的桩什么是内联?
Go 单元测试工具
测试分为四个级别。
单元:测试代码。集成测试:测试服务的接口。端到端测试(链接测试):从一个链接的入口输入测试用例,验证系统的输出UI测试。
常见错误:
没有断言。没有断言的单一测试是没有灵魂的。
单次测量的特点:
答:(自动):单元测试应该是全自动的、非交互式的I:(独立):为了保证单元测试稳定、可靠、易于维护,单元测试用例绝对不能互相调用,也不能依赖于执行的顺序。R: (Repeatable):单元测试通常被放入持续集成中,并且将在每次代码检入时被执行。
单测
bug总是不可避免的。越早发现问题,解决问题的成本越低。单一测试可以尽早暴露错误。改进代码的方式,使项目能够以更高的质量交付。至少有三个好处:
提高代码质量。
编写单个测试是自测的一部分。在编写新代码的时候加入相应的单项测试,可以帮助我们发现大部分bug,减少调试时的调整,提高调试效率。
在功能测试上花费更少的时间
功能测试的成本相对较高,因为往往需要执行一系列操作来验证结果是否符合预期。如果发现问题,沟通和复试往往要花很多时间。
在回归测试上花费更少的时间
回归测试是为了避免在对应用程序进行更改时引入错误。测试人员不仅要测试他们的新功能,还要测试现有的功能,以验证之前实现的功能是否仍然如预期的那样工作。通过单元测试,您可以在每次构建后重新运行整个测试过程,以确保新代码不会破坏现有的功能。
测试异常场景
有些异常场景QA不好构建,比如资金是否安全,交易异常相关测试等等。这些异常场景中往往会出现问题,可能会导致线上出现问题,甚至发生意外。单元测试可以通过mock方便地模拟各种异常场景。
Go 单元测试工具
gomonkey
引入gomonkey有以下好处:
隔离测试中的代码,加速测试的执行,使执行决定模拟特殊情况。
功能列表
支持堆栈函数、堆栈函数的特定序列、堆栈成员方法、堆栈成员方法的特定序列、堆栈函数变量、堆栈函数变量的特定序列、堆栈接口、堆栈接口的特定序列和堆栈全局变量。
函数堆栈和变量模拟实现的原理和gostub一样,都是通过reflect包实现的。除了模仿变量,gomonkey还可以直接模仿模仿代码所在的包的导出函数/方法和非导出函数。
去猴子许可被拒解决方案:https://github.com/eisenxp/macos-golink-wrapper
mv $ go root/pkg/tool/Darwin _ amd64/link $ go root/pkg/tool/Darwin _ amd64/original _ link
CP https://github.com/eisenxp/macos-golink-wrapper/link $ go root/pkg/tool/Darwin _ amd64/link
下载文件,然后cp
wget https://raw . githubusercontent . com/eisen XP/MAC OS-golink-wrapper/main/link
Gomonkey提供了以下模拟方法:
ApplyGlobalVar (target,double interface {}):使用reflect包将target的值修改为DoubleApplyFuncVar (target,double interface {}):检查目标是否为指针类型,是否与double函数声明相同?最后调用ApplyGlobalVarApplyFunc (target,double interface {}):修改目标的机器指令,跳转到double执行ApplyMethod(target reflect。Type,Method string,double interface {}):修改方法的机器指令,跳转到double执行applyfuncseq (target interface {},outputs [] output cell):修改目标的机器指令,跳转到执行gomonkey生成的一个函数,每次调用都会从outputs中顺序取出一个值,返回给applymethodseq(target reflect . type,method name string,outputs [] output cell):修改目标的机器指令, 跳转到gomonkey生成的一个方法的执行,每次调用都会从outputs中顺序取出一个值,返回给ApplyFuncVarSeq(目标接口{},outputs [] output cell): Gomonkey生成一个函数,顺序返回outputs中的值,调用ApplyGlobalVar。
gomonkey 打桩失败的可能原因
Gomonkey不是并发安全的。如果有多个通道并堆积到同一个目标,则有必要优雅地退出前一个通道。堆积目标是内联函数或成员方法。可以通过命令行参数-GC flags=-l(go 1.10版之前)或-GC flags=all=-l(go 1.10版之后)关闭内联优化。Gomonkey无法堆积私有成员方法。go的go1.6版本的反射机制支持私有成员方法的查询,而1.7及以后的版本不支持,所以当用户使用1.7及以后的版本时,gomonkey对私有成员方法的打桩会触发异常。
goconvey
为全局变量打一个桩
包装单元测试
导入(
'测试'
' github . com/agiled ragon/gomonkey '
' github . com/smarty streets/go convey/convey '
)
var=10//全局变量
func TestApplyGlobalVar(t *测试。T) {
传达。Convey('TestApplyGlobalVar ',t,func() {
传达。Convey('change ',func() {
补丁:=gomonkey。ApplyGlobalVar(编号,150)
推迟修补程序。重置()
传达。所以(小水,传达。ShouldEqual,150)
})
传达。传送(' recover ',func() {
传达。所以(小水,传达。ShouldEqual,10)
})
})
}
执行结果:
===运行TestApplyGlobalVar
.
2个总断言
-通过:TestApplyGlobalVar (0.00s)
及格
为一个函数打桩
func networkCompute(a,b int) (int,error) {
//在远程计算机中做一些事情
丙:=甲乙
返回c,零
}
func Compute(a,b int) (int,error) {
sum,err :=networkCompute(a,b)
返回总和,错误
}
func test func(t *测试。T) {
//嘲讽了networkCompute(),返回了计算结果2。
补丁:=gomonkey。ApplyFunc(networkCompute,func(a,b int) (int,error) {
返回2,零
})
推迟修补程序。重置()
sum,err :=Compute(1,2)
println('预期%v,得到%v ',2,sum)
if sum!=2 || err!=零{
t.Errorf('应为%v,得到%v ',2,sum)
}
}
结果:
===运行TestFunc
应为%v,但得到的是%v 2 3
mock_func_test.go:91:需要2个,得到3个
-失败:test func(0.00秒)
失败
可以看到上面的结果。如果执行失败,模拟也会失败。
有时,mock会失败,这通常是由内联引起的。
什么是内联?
为了减少调用函数时的堆栈等开销,对于短函数,编译时会直接嵌入调用代码。
我们禁用较低的内联,然后执行,go test-v-GC flags=-lmock _ func _ test . go。
执行结果:
===运行TestFunc
应为%v,但得到了% v 2 2
-通过:测试函数(0.00秒)
及格
对于go 1.10以下的版本,可以使用-gcflags=-l禁用内联,对于go 1.10以上的版本,可以使用-gcflags=all=-l。但目前来看,还可以用。关于gcflags的用法,可以使用gotool compile-help来检查gcflags各个参数的含义。
这就是这篇关于单元测试工具gomonkey的使用的文章。想了解更多关于Go Monkey的信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。