HTTP/2
如何测试 HTTP/2 协议
HTTP/2 协议介绍
HTTP/2 相比于 HTTP/1.1,在完全兼容语义的基础上,新增支持了多路复用、二进制分帧、首部压缩、服务端推送等特性,大幅提升了 Web 性能,当前已经进行了较为广泛的应用。
HttpRunner 从 v4.0 开始新增实现了对 HTTP/2 协议的测试支持。
脚本准备
虽然 HTTP/2 协议跟 HTTP/1.1 具有非常大的差异,但从测试脚本的角度,将已有的 HTTP/1.1 脚本升级为 HTTP/2 非常容易,只需要新增一个 http2
描述字段即可;而在请求参数描述、参数关联、结果断言等使用方法方面跟之前的 HTTP/1.1 基本保持了一致。
下面将通过实际的测试用例展示 HTTP/2 脚本的修改方法。
YAML 脚本格式示例
对于 JSON/YAML 形态的测试用例,只需要在 request
对象中添加一个新字段 http2
并且指定为 true
。
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 # 只需指定 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
另外,HttpRunner v4.0 也新增支持了对协议类型的断言(“check”: “proto”),这对于判断服务端是否支持 HTTP/2 的场景来说是非常实用的,因为有时候服务端不支持 HTTP/2 并且会自动降级为 HTTP/1.1,这时就有必要对协议类型进行断言。
GoTest 脚本格式示例
对于 go test 形态的测试用例,将 HTTP/1.1 升级为 HTTP/2 的方式同样非常简单,只需要在调用链中的 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(). // 只需新增调用 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