使用 HttpRunner v4.0 实现 HTTP/2 的测试

前言回顾

此前的文章 HttpRunner v4.0 正式发布 中提到,HttpRunner v4.0 已不再局限于 HTTP 协议,而是会拓展支持更多种类的网络协议,截至当前,HttpRunner v4.0 中 go 引擎已经新增支持了 HTTP/2 协议 和 WebSocket 协议,python 引擎也已经新增支持了 SQL 操作和 Thrift RPC 协议。本期文章将对支持 HTTP/2 的新特性进行介绍,对于 HttpRunner v4.0 的其他新特性,之后也将会陆续进行介绍,敬请期待。

特性介绍

对于原有的包含 HTTP/1.1 请求的测试脚本,将协议类型升级为 HTTP/2 的修改成本非常低,在添加请求参数、请求头和请求体等操作方面,HTTP/2 的测试用例与 HTTP/1.1 的风格基本保持一致,同时也继承了 HttpRunner 强大的参数关联和结果断言等功能。下面介绍将测试用例中的协议类型由 HTTP/1.1 升级为 HTTP/2 的具体修改方式。

JSON/YAML 形态的测试用例

对于 JSON/YAML 形态的测试用例,只需要在 request 对象中添加一个新字段 http2 并且指定为 true。另外,新版本 HttpRunner 也支持对协议类型的断言(“check”: “proto”),这对于判断服务端是否支持 HTTP/2 的场景来说是非常实用的,因为有些时候服务端不支持 HTTP/2 并且会自动降级为 HTTP/1.1,这时就有必要对协议类型进行断言。如下是一个 HTTP 协议升级之后的 JSON 测试用例,在原来的基础上,只增加了一行代码 "http2": true 即可将 HTTP/1.1 升级为 HTTP/2,YAML 脚本同理,此处不再赘述。

{
    "config": {
        "name": "run request with HTTP/2",
        "base_url": "https://postman-echo.com"
    },
    "teststeps": [
        {
            "name": "HTTP/2 get",
            "request": {
                "method": "GET",
                "url": "/get",
                "http2": true,
                "params": {
                    "foo1": "foo1",
                    "foo2": "foo2"
                },
                "headers": {
                    "User-Agent": "HttpRunnerPlus"
                }
            },
            "validate": [
                {
                    "check": "status_code",
                    "assert": "equals",
                    "expect": 200,
                    "msg": "check status code"
                },
                {
                    "check": "proto",
                    "assert": "equals",
                    "expect": "HTTP/2.0",
                    "msg": "check protocol type"
                },
                {
                    "check": "body.args.foo1",
                    "assert": "length_equals",
                    "expect": 4,
                    "msg": "check param foo1"
                }
            ]
        }
    ]
}

go test 形态的测试用例

对于 go test 形态的测试用例,将 HTTP/1.1 升级为 HTTP/2 的方式同样非常简单,只需要在调用链中的 GET、POST 等请求方法之前先调用 HTTP2() 即可。如下是一个 HTTP 协议升级之后的 go test 测试用例,请注意 hrp.NewStep 方法与 GET、POST 请求方法之间新增的 HTTP2() 调用。

package tests

import (
   "testing"

   "github.com/httprunner/httprunner/hrp"
)

func TestHTTPProtocol(t *testing.T) {
   testcase := &hrp.TestCase{
      Config: hrp.NewConfig("run request with HTTP/1.1 and HTTP/2").
         SetBaseURL("https://postman-echo.com"),
      TestSteps: []hrp.IStep{
         hrp.NewStep("HTTP/2 get").
            HTTP2().
            GET("/get").
            WithParams(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
            WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
            Validate().
            AssertEqual("status_code", 200, "check status code").
            AssertEqual("proto", "HTTP/2.0", "check protocol type").
            AssertLengthEqual("body.args.foo1", 4, "check param foo1"),
         hrp.NewStep("HTTP/2 post").
            HTTP2().
            POST("/post").
            WithHeaders(map[string]string{"User-Agent": "HttpRunnerPlus"}).
            WithBody(map[string]interface{}{"foo1": "foo1", "foo2": "foo2"}).
            Validate().
            AssertEqual("status_code", 200, "check status code").
            AssertEqual("proto", "HTTP/2.0", "check protocol type").
            AssertLengthEqual("body.json.foo1", 4, "check body foo1"),
      },
   }
   err := hrp.NewRunner(t).Run(testcase)
   if err != nil {
      t.Fatalf("run testcase error: %v", err)
   }
}

注意事项

  • 在使用 hrp run 进行接口测试时,通过命令行选项 --proxy-url 设置的代理 URL 对于 HTTP/2 协议的请求不会生效,原因是底层依赖不支持设置代理 URL
  • 在使用 hrp boom 进行性能测试时,通过命令行选项 --disable-keepalive 设置的打开/关闭长连接对于 HTTP/2 协议的请求不会生效,原因是底层依赖不支持设置改参数,另外 HTTP/2 协议支持多路复用,可以天然地达到类似长连接的效果
  • 虽然 RFC 文档中没有强制规定,不过目前大部分 HTTP/2 服务是建立在 SSL/TLS 之上的,因此建议在 URL 中使用 HTTPS

What’s next

目前 hrp har2case 命令还不支持将包含 HTTP/2 请求的 har 包转换为 JSON/YAML 测试用例,HttpRunner v4.0 之后的版本中将会对该特性进行支持

本文作者:卜卜星(HttpRunner 核心开发者)
HttpRunner 项目官网: https://httprunner.com/
如果 HttpRunner 对你有过帮助,麻烦帮忙给个 ⭐️star⭐️ 鼓励下吧
https://github.com/httprunner/httprunner