HttpRunner 【二次开发】httprunner V4 版本通过 hooks 实现加解密

扬帆自动化测试平台 · January 06, 2023 · Last by 扬帆自动化测试平台 replied at January 17, 2023 · 6624 hits

为何进行二次开发

  1. 有 hooks 机制,但是调用时发现和 v3 版本不一样,识别不到 request 和 response 两个变量,查看源码发现加了前缀hrp_step_
  2. 查看例子,发现 hook 对应的函数并没有返回,v3 中自定义函数只支持 python,在自定义函数中可以直接对 request 进行修改,由于 v4 用的是 plugin,所以需要有返回值才可以

分析源码

通过源码得知 SetupHooks 和 TeardownHooks 并没有返回值,只要加上返回值,然后给 rb.requestMap 重新赋值,同时也要给 rb.req 赋值,rb.req 是实际请求数据,在之前就处理过了,所以这里需要再进行处理

package hrp

func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err error) {
    // ... 省略

    // add request object to step variables, could be used in setup hooks
    stepVariables["hrp_step_name"] = step.Name
    stepVariables["hrp_step_request"] = rb.requestMap

    // deal with setup hooks
    for _, setupHook := range step.SetupHooks {
        _, err = parser.Parse(setupHook, stepVariables)
        if err != nil {
            return stepResult, errors.Wrap(err, "run setup hooks failed")
        }
    }

    // ... 省略
}

修改源码

以 SetupHooks 为例

  1. 函数内修改数据,但是不能改变 request 的结构 python def setup_hook_encryption(request): request["body"]["setup_hook_encryption_request"] = "setup_hook_encryption_request" return request
  2. stepVariables 增加 request,兼容 v3 的写法
  3. 数据写入 rb.requestMap
  4. 数据写入 rb.req.Body,修改后需要修改 ContentLength,否则会因为长度不一致导致报错
package hrp

func runStepRequest(r *SessionRunner, step *TStep) (stepResult *StepResult, err error) {
    // ... 省略

    // add request object to step variables, could be used in setup hooks
    stepVariables["hrp_step_name"] = step.Name
    stepVariables["hrp_step_request"] = rb.requestMap
    stepVariables["request"] = rb.requestMap

    // deal with setup hooks
    for _, setupHook := range step.SetupHooks {
        req, err := parser.Parse(setupHook, stepVariables)
        if err != nil {
            return stepResult, errors.Wrap(err, "run setup hooks failed")
        }
        reqMap, ok := req.(map[string]interface{})
        if ok {
            rb.requestMap = reqMap
            stepVariables["request"] = reqMap
        }
    }
    if len(step.SetupHooks) > 0 {
        requestBody, ok := rb.requestMap["body"].(map[string]interface{})
        if ok {
            body, err := json.Marshal(requestBody)
            if err == nil {
                rb.req.Body = io.NopCloser(bytes.NewReader(body))
                rb.req.ContentLength = int64(len(body))
            }
        }
    }

    // ... 省略

}
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 6 条回复 时间 点赞

给 HttpRunner 提个 PR 呗

请问下 httprunner 中 debugtalk.py 怎么引用.env 中的配置(不是 testcase 中引用,是 debugtalk 中引用),有什么内置函数吗?不然只能自己写个函数处理了

IAmTester 回复

4.x 和 3.x 实现方式的区别

4.x 因为实现方式问题是没办法在 debugtalk 中引用.env 的,4.x 的 debugtalk 是运行一个 grpc 服务,数据与 hrp 运行的数据是隔离的,3.x 是在内部调用函数,在运行的生命周期内数据应该是可以互通的,因为实现方式不一样,所以像 hooks 也需要把修改后的数据返回给用例,然后再进行操作。

4.x 如何在 debugtalk 中引用 env

如果要引用,只能通过函数传参的形式,或者在 debugtalk 中定义一个全局变量,然后在 config 中调用并传参 env,后面的函数就可以直接引用 env 的数据。

单个用例即使报告时通过的也会报:httprunner 的报告提示 OSError: [WinError 6] 句柄无效。==============请问下这该如何解决,我运行测试报告的命令是:hrun testcases --html=./reports/result.html --self-contained-html

IAmTester 回复

可以参考一下httprunner 查看报告提示 OSError: [WinError 6] 句柄无效 ,hrun 这个应该是 python 运行的,对于 python 源码比较少看,所以比较陌生

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up