Go测试技术分享(一):场景化接口Case编写
时间:2021-08-07
本文章向大家介绍Go测试技术分享(一):场景化接口Case编写,主要包括Go测试技术分享(一):场景化接口Case编写使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、前言
本人负责的支付清结算方向的测试工作,在测试项目中,会出现流程化的接口调用,请求完一个接口后,继续请求另一个接口(这里的接口可以指Http,也指rpc接口),这里以一个真实场景为例:用户在平台下单,结算前部分退款,再结算,最后结算后部分退款;
第一个接口动作对应用户下单,第二个动作对应结算前的部分退款,第三个动作对应结算,第四个动作对应结算后的部分退款,涉及不同系统的交互;这是一个完整的场景,根据我们的测试用例与更多的用户场景,实际测试中,我们需要测试更多场景,单接口测试已无法满足实际需求。
二、表格驱动测试
我们可以定义一个结构体,将每一个步骤定义成一个节点,通过遍历节点达到执行整个流程的效果:
优点就是代码更加清晰、明确,也便于调整步骤的顺序、新增或者移除某些步骤。另外,在循环体中增加调试日志也非常的简单;
但还是有缺点的,看上去似乎不满足接口测试一些要求,没有case管理,无法做接口断言等
func main() { ctx := &context{} steps := []struct { name string fn func() error }{ {"parse flags", ctx.parseFlags}, {"read schema", ctx.readSchema}, {"dump schema", ctx.dumpSchema}, // Before transformations {"remove builtin constructors", ctx.removeBuiltinConstructors}, {"add adhoc constructors", ctx.addAdhocConstructors}, {"validate schema", ctx.validateSchema}, {"decompose arrays", ctx.decomposeArrays}, {"replace arrays", ctx.replaceArrays}, {"resolve generics", ctx.resolveGenerics}, {"dump schema", ctx.dumpSchema}, // After transformations {"decode combinators", ctx.decodeCombinators}, {"dump decoded combinators", ctx.dumpDecodedCombinators}, {"codegen", ctx.codegen}, } for _, step := range steps { ctx.debugf("start %s step", step.name) if err := step.fn(); err != nil { log.Fatalf("%s: %v", step.name, err) } } }
三、封装
将场景和节点定义成结构体,提供场景与节点独立的执行接口:
实际的节点,需要定义成这个结构体的方法;
type SenceSuite struct { SenceSuite string } type Plan struct { Planname string Fn func(map[string]interface{}) interface{} Data map[string]interface{} } var SenceSuiteDao *SenceSuite var SenceSuiteOnce sync.Once func NewSenceSuiteDao() *SenceSuite { SenceSuiteOnce.Do( func() { SenceSuiteDao = &SenceSuite{} }) return SenceSuiteDao } func (dao *SenceSuite) DoSence(steps []Plan) { for _, step := range steps { step.Fn(step.Data) } } func (dao *SenceSuite) DoPlan(step Plan) interface{} { return step.Fn(step.Data) }
四、实际使用
接口case管理:"github.com/smartystreets/goconvey/convey"
这里仍然以上面的场景为例:
//结算前部分退款,再结算,部分退款 func TestRefundAndNomalSettleAndRefund(t *testing.T) { // 初始化数据库 utils.DBInit() //用户下单 order := GetOrder("ZFB", "SELF", "nrmol") env := "prod" way := "1" SenceSuite := utils.NewSenceSuiteDao() convey.Convey("结算前部分退款", t, func() { P1 := utils.Plan{Planname: "结算前部分退款", Fn: SenceSuite.Refund, Data: map[string]interface{}{}} res := SenceSuite.DoPlan(P1).(*xxx) convey.So(res.RetCode, convey.ShouldEqual, "000000") }) convey.Convey("正常结算", t, func() { P2 := utils.Plan{Planname: "正常结算", Fn: SenceSuite.Settle, Data: map[string]interface{}{}} res := SenceSuite.DoPlan(P2).(*xxx) convey.So(res.RetCode, convey.ShouldEqual, "000000") }) convey.Convey("结算后部分退款", t, func() { P3 := utils.Plan{Planname: "结算后部分退款", Fn: SenceSuite.Refund, Data: map[string]interface{}{}} res := SenceSuite.DoPlan(P3).(*xxx) convey.So(res.RetCode, convey.ShouldEqual, "000000") }) }
原文地址:https://www.cnblogs.com/-wenli/p/15111773.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法