一、前言

  本人负责的支付清结算方向的测试工作,在测试项目中,会出现流程化的接口调用,请求完一个接口后,继续请求另一个接口(这里的接口可以指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")
})
}

  

  

  

最新文章

  1. 慕课网__CSS__ Relative, absolute,
  2. CSS各种定位详解
  3. Python学习笔记09
  4. C++11中对类(class)新增的特性
  5. 第二十三课:jQuery.event.add的原理以及源码解读
  6. 【转】Paxos算法深入分析
  7. MERGE语法详解
  8. ansible编译httpd playbook示例
  9. Error: expected expression, got '}'
  10. 关于php日期前置是否有0
  11. C语言作业04-数组
  12. appium 手势
  13. [java大数据面试] 2018年4月百度面试经过+三面算法题:给定一个数组,求和为定值的所有组合.
  14. 解决logstash启动缓慢问题
  15. 【转】利用线程更新ListView (2014-09-28 08:25:20)
  16. [转]VUE优秀UI组件库合集
  17. Linux CPU使用率的计算
  18. 在MFC中改变控件的TAB顺序
  19. hadoop19---动态代理
  20. FileSearch.java

热门文章

  1. ZooKeeper分布式锁的实现
  2. excel用函数去掉单元格内容中的括号,并只保留单元格里面的内容
  3. 2、mysql编译安装
  4. hdu 1540 Tunnel Warfare 线段树 区间合并
  5. Springboot整合shardingsphere和druid进行读写分离
  6. 3、集成springfox-swagger 3.0.0 + 集成knife4j
  7. Hibernate框架(四)缓存策略+lazy
  8. Linux date 获取时间
  9. 【重学Java】IO流
  10. ROS踩坑笔记总结