httprunner 支持在测试步骤里面使用关键字:extract 提取响应体中的数据,支持jmesPath路径和正则两种方式提取数据
teststeps:
-
name: test
request:
method: POST
url:
extract:
list: body.list // 通过jmesPath 提取json格式数据
title: "<title>(.*)</title>" // 通过正则提取数据
当我们需要对提取内容做一定处理在返回,或者两种提取方式不能满足实际使用时,我们就需要对响应体做自定义处理
我们可以通过在:extract 中使用函数,将响应体传入到函数中,由函数处理后返回我们想要的结果,例如:我们有一个函数GetDiyData()用于处理提取自定义参数
teststeps:
-
name: test
request:
method: POST
url:
extract:
list: body.list
title: "<title>(.*)</title>"
diy: ${GetDiyData($hrp_step_response)} #调用自定义函数提取
我们在:extract 中调用自己实现的函数:${GetDiyData()} 对影响体处理,并返回我们想要的数据,那如何将响应体传入到函数中呢?这里通过源码可以看到作者已经将响应体数据存放的变量中了,我们只需要通过引用变量的方式即可获取到完整的响应体,在变量Map中存储响应体的key为:hrp_step_response,所以我们在调用自定义函数时这样传递:${GetDiyData($hrp_step_response)}
// do request action
start := time.Now()
// 获取接口响应
resp, err := client.Do(rb.req)
if err != nil {
return stepResult, errors.Wrap(err, "do request failed")
}
if resp != nil {
defer resp.Body.Close()
}
·····
// 初始化一个响应对象
respObj, err := newHttpResponseObject(r.caseRunner.hrpRunner.t, parser, resp)
if err != nil {
err = errors.Wrap(err, "init ResponseObject error")
return
}
·····
// 将响应数据放到步骤的变量中,获取的关键字:hrp_step_response
// add response object to step variables, could be used in teardown hooks
stepVariables["hrp_step_response"] = respObj.respObjMeta
具体的GetDiyData()函数就可以在插件中写,然后编译成bin文件,这样在测试步骤中就可以引用到了
// 响应体如果不确定是什么类型时则使用interface{}类型接收,最后在返回interface{}类型
func GetDiyData(args interface{})interface{}{
// 此时即可实现对响应的自定义处理了
// 写完之后记得重新编译bin文件,这样在测试步骤中自定义提取函数就可以正常使用了
return nil
}
个栗子
接口响应体为一个数组:[0,1,2,3,4,5],希望提取到响应数据数组中所有值的和
func GetSliceSum(resp map[string]interface{}) interface{} {
var sum float64
body := resp["body"] // 提取到响应的body参数
ty := reflect.TypeOf(body)
if ty.Kind() == reflect.Slice {
val := reflect.ValueOf(body) // 反射获取到body参数值
for i := 0; i < val.Len(); i++ {
// 在反射获取到数组中元素的值,并与sum相加
sum += reflect.ValueOf(val.Index(i).Interface()).Float()
}
}
return sum
}
拓展:接收到参数 resp 取值字段:"proto", "status_code", "headers", "cookies", "body"