目录
了解 get put post delete head patch options 方法,并配置查询参数、HTTP 检查、multipart 和请求正文.
请注意,大多数方法可以采用静态值、gatling表达式语言 (EL) 字符串和函数作为参数。
HTTP 支持有一个专用的 DSL,其入口点是 http(requestName) 方法。此请求名称很重要,因为它将在计算报告的统计信息时充当键。 如果同一名称出现在模拟中的多个位置,Gatling 将认为这些请求属于同一类型,并且它们的统计信息将被汇总。
// 常量
http("requestName").get("https://gatling.io")
// 常量
http("#{requestName}").get("https://gatling.io")
// 常量
http(session => session("requestName").as[String]).get("https://gatling.io")
如您所见,请求名称可以是动态的。 但是,我们建议您不要滥用此功能并最终得到大量不同的值。 您会给报告模块带来巨大的负担,并且您的统计数据可能更难分析并且可能没有意义(每个请求名称没有足够的值)。
HTTP 请求必须传递给 exec() 方法才能附加到场景并被执行。
// 内联样式
scenario("ScenarioName")
.exec(http("RequestName").get("url"))
// 非内联样式
val request = http("RequestName").get("url")
scenario("ScenarioName")
.exec(request)
Gatling 为最常用的方法提供了内置插件。 这些只是小写的方法名称。
// 绝对路径
http("name").get("https://gatling.io")
// 绝对路径
http("name").get("#{url}")
// 绝对路径
http("name").get(session => session("url").as[String])
http("name").put("https://gatling.io")
http("name").post("https://gatling.io")
http("name").delete("https://gatling.io")
http("name").head("https://gatling.io")
http("name").patch("https://gatling.io")
http("name").options("https://gatling.io")
http("name").httpRequest("PURGE", "http://myNginx.com")
Gatling 还支持相对 url,请参阅 baseUrl。
框架和开发人员经常在查询中传递附加信息,即 url 后面的部分。 查询由键=值对组成,用 & 分隔。 这些是命名的查询参数。
例如,https://github.com/gatling/gatling/issues?milestone=1&state=open 包含 2 个查询参数:
milestone=1
:参数名是milestone, 参数值是1state=open
: 参数名是state ,参数值是open查询参数键和值必须按照 `RFC3986](http://tools.ietf.org/html/rfc3986) 进行 URL 编码。 默认情况下,Gatling 会尝试处理此编码,但您可以禁用它,请参阅 disableUrlEncoding。
为了设置 HTTP 请求的查询参数,您可以:
要么在 url 中传递完整的查询,例如:
http("Issues")
.get("https://github.com/gatling/gatling/issues?milestone=1&state=open")
或者将查询参数一一传递给名为 queryParam 的方法:
// 常量
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "1")
.queryParam("state", "open")
// Gatling EL字符串
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", "#{milestoneValue}")
.queryParam("state", "#{stateValue}")
// 函数
http("Issues").get("https://github.com/gatling/gatling/issues")
.queryParam("milestone", session => session("milestoneValue").as[String])
.queryParam("state", session => session("stateValue").as[String])
您可以使用 multivaluedQueryParam 设置具有多个值的查询参数:
http("name").get("/")
// 常量
.multivaluedQueryParam("param", Seq("value1", "value2"))
http("name").get("/")
// 带有指向 Seq 的 Gatling EL 字符串
.multivaluedQueryParam("param", "#{values}")
http("name").get("/")
// 函数
.multivaluedQueryParam("param", session => Seq("value1", "value2"))
您可以使用 queryParamSeq 和 queryParamMap 一次设置多个查询参数:
http("name").get("/")
.queryParamSeq(Seq(("key1", "value1"), ("key2", "value2")))
http("name").get("/")
.queryParamMap(Map("key1" -> "value1", "key2" -> "value2"))
header
HTTP 协议使用headers在客户端和服务器之间交换不属于消息主体的信息。
Gatling HTTP 允许您使用 header 和 headers 方法指定您想要的任何请求头。
// 提取标头映射允许您在多个请求中重用这些请求头
val sentHeaders = Map(
"content-type" -> "application/javascript",
"accept" -> "text/html"
)
http("name").get("/")
// 一次添加多个请求头信息
.headers(sentHeaders)
// 添加其他请求头信息
.header("keep-alive", "150")
// 覆盖请求头中的content-type
.header("content-type", "application/json")
请求头中的参数名被定义为场景中可用的常量,例如:HttpHeaderNames.ContentType。 您可以在此处找到预定义常量的列表。
asXXX
Gatling 提供了一些方便的快捷方式来设置 JSON、XML 和表单编码所需的headers:
// asJson
http("name").post("/")
.asJson
// asJson是以下写法的快捷方式:
http("name").post("/")
.header("accept", "application/json")
.header("content-type", "application/json")
// asXml
http("name").post("/")
.asXml
// asXml是以下写法的快捷方式:
http("name").post("/")
.header("accept", "application/xhtml+xml")
.header("content-type", "application/xhtml+xml")
// asFormUrlEncoded
http("name").post("/")
.asFormUrlEncoded
// asFormUrlEncoded是以下写法的快捷方式:
http("name").post("/")
.header("content-type", "application/application/x-www-form-urlencoded")
// asMultipartForm
http("name").post("/")
.asMultipartForm
// asMultipartForm是以下写法的快捷方式:
http("name").post("/")
.header("content-type", "multipart/form-data")
共享headers也可以在 HttpProtocol 上定义。
对于给定的请求,您还可以使用 ignoreProtocolHeaders 禁用共享的 HttpProtocol 标头。
http("name").get("/")
.ignoreProtocolHeaders
您可以对请求添加检查。
http("name").get("/")
.check(status.is(200))
有关详细信息,请参阅 HTTP 检查参考部分。
对于给定的请求,您还可以使用 ignoreProtocolChecks 禁用在 HttpProtocol 上定义的常见检查:
http("name").get("/")
.ignoreProtocolChecks
在本节中,您可以找到设置完整请求正文的各种方法。
正文模板位置的解析方式与 Feeder 文件相同。文件必须放在:
不要使用相对文件系统路径,例如 src/main/resources/data/foo.txt,而是使用类路径路径 data/foo.txt。
您可以使用专用方法body向 HTTP 请求添加完整body,其中body可以是:
StringBody
StringBody 允许您传递代码中定义的文本参数。 用于在线路上写入字节的字符集是在 Content-Type 请求头的字符集属性中定义的字符集(如果已定义),否则为在 gatling.conf 中定义的字符集。
此解决方案通常与 Gatling 表达式语言格式的字符串一起使用。
它需要一个参数:
string 文本内容,可以是纯字符串、gatling表达式语言字符串或函数。
// 常量请求body
http("name").post("/")
.body(StringBody("""{ "foo": "staticValue" }"""))
// 带有Gatling EL字符串的body
http("name").post("/")
.body(StringBody("""{ "foo": "#{dynamicValue}" }"""))
// 带有函数的请求body
http("name").post("/")
.body(StringBody(session => s"""{ "foo": "${session("dynamicValueKey").as[String]}" }"""))
使用函数是制作复杂动态负载的一种方法,因为您可以编写自己的逻辑。
object Templates {
val template: Expression[String] = session =>
for {
foo <- session("foo").validate[String]
bar <- session("bar").validate[String]
} yield s"""{ "foo": "$foo", "bar": "$bar" }"""
}
http("name").post("/")
.body(StringBody(Templates.template))
RawFileBody
RawFileBody 允许您传递一个原始文件,其字节将按原样发送,这意味着它可以是二进制内容。 这种方式是最有效的方式,因为字节可以被缓存,而不必解码为文本,然后重新编码回字节以写入网络。
它需要一个参数:
// 静态路径
http("name").post("/")
.body(RawFileBody("rawPayload.json"))
// Gatling表达式路径
http("name").post("/")
.body(RawFileBody("#{payloadPath}"))
// 函数路径
http("name").post("/")
.body(RawFileBody(session => session("payloadPath").as[String]))
ElFileBody
ElFileBody 允许您传递一些从 Gatling 表达式语言格式的模板文件解析的文本内容。
它需要一个参数:
由于 Gatling 表达式是基于文本的模板引擎,因此内容不能是非文本的。
http("name").post("/")
.body(ElFileBody("rawPayload.json"))
// with a Gatling EL String path
http("name").post("/")
.body(ElFileBody("#{payloadPath}"))
// with a function path
http("name").post("/")
.body(ElFileBody(session => session("payloadPath").as[String]))
PebbleStringBody
就原始性能而言,gatling表达式语言无疑是gatling最优的模板引擎。 但是,您可以在其中实现的逻辑有点有限。 如果你想要循环和条件块,你可以使用 Gatling 基于 Pebble 的模板引擎。
http("name").post("/")
.body(PebbleStringBody("""{ "foo": "{% if someCondition %}{{someValue}}{% endif %}" }"""))
您可以使用 registerPebbleExtensions(extensions: Extension*) 注册 Pebble Extensions。 这只能完成一次,并且必须在加载任何 Pebble 模板之前完成。
模板继承仅在使用 PebbleFileBody 时可用。
PebbleFileBody
PebbleFileBody 允许您将路径传递给 Pebble 文件模板。
// with a static value path
http("name").post("/")
.body(PebbleFileBody("pebbleTemplate.json"))
// with a Gatling EL string path
http("name").post("/")
.body(PebbleFileBody("#{templatePath}"))
// with a function path
http("name").post("/")
.body(PebbleFileBody(session => session("templatePath").as[String]))
ByteArrayBody
ByteArrayBody 允许您传递一个字节数组,通常在您想要使用诸如 Protobuf 之类的二进制协议时。
// with a static value
http("name").post("/")
.body(ByteArrayBody(Array[Byte](0, 1, 5, 4)))
// with a static value
http("name").post("/")
.body(ByteArrayBody("#{bytes}"))
// with a function
http("name").post("/")
.body(ByteArrayBody(session =>
Base64.getDecoder.decode(session("data").as[String]))
)
InputStreamBody
InputStreamBody 允许您传递 java.util.InputStream。
http("name").post("/")
.body(InputStreamBody(session => new ByteArrayInputStream(Array[Byte](0, 1, 5, 4))))
本节指的是使用 application/x-www-form-urlencoded 或 multipart/form-data 编码的有效负载,用于 HTML 表单。
除非您明确设置 Content-Type:
formParam
formParam 允许您传递非文件表单输入字段。
// with static values
http("name").post("/")
.formParam("milestone", "1")
.formParam("state", "open")
// with Gatling EL strings
http("name").post("/")
.formParam("milestone", "#{milestoneValue}")
.formParam("state", "#{stateValue}")
// with functions
http("name").post("/")
.formParam("milestone", session => session("milestoneValue").as[String])
.formParam("state", session => session("stateValue").as[String])
您可以使用 multivaluedFormParam 设置具有多个值的表单参数:
http("name").post("/")
// with static values
.multivaluedFormParam("param", Seq("value1", "value2"))
http("name").post("/")
// with a Gatling EL string pointing to a Seq
.multivaluedFormParam("param", "#{values}")
http("name").post("/")
// with a function
.multivaluedFormParam("param", session => Seq("value1", "value2"))
您可以使用 formParamSeq 和 formParamMap 一次设置多个表单参数:
http("name").post("/")
.formParamSeq(Seq(("key1", "value1"), ("key2", "value2")))
http("name").post("/")
.formParamMap(Map("key1" -> "value1", "key2" -> "value2"))
form
您可能希望重新请求,使用的数据是之前通过表单检查捕获的所有输入或表单。(可以用于调试场景)
请注意,您可以使用 formParam 等覆盖表单字段值。
http("name").post("/")
.form("#{previouslyCapturedForm}")
// override an input
.formParam("fieldToOverride", "newValue")
formUpload
此方法采用 2 个参数:
见上文 Gatling 如何解析 filePath。
// with a static filepath value
http("name").post("/")
.formParam("key", "value")
.formUpload("file1", "file1.dat")
// you can set multiple files
.formUpload("file2", "file2.dat")
// with a Gatling EL string filepath
http("name").post("/")
.formUpload("file1", "#{file1Path}")
// with a function filepath
http("name").post("/")
.formUpload("file1", session => session("file1Path").as[String])
上传文件的 MIME 类型默认为 application/octet-stream,字符集默认为 gatling.conf 中配置的字符集(默认为 UTF-8)。 在需要时覆盖它们。
bodyPart
您可以使用 bodyPart 将多部分实体设置为单独的部分。
// set a single part
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
)
// set a multiple parts
http("name").post("/")
.bodyParts(
StringBodyPart("partName1", "value"),
StringBodyPart("partName2", "value")
)
asXXX 快捷方式可以帮助您配置必要的 HTTP headers。
使用以下方法之一引导后,BodyPart 具有以下用于设置附加选项的方法。 与 DSL 的其余部分一样,几乎每个参数都可以是纯字符串、gatling表达式语言字符串或函数。
http("name").post("/")
.bodyPart(
StringBodyPart("partName", "value")
.contentType("contentType")
.charset("utf-8")
// part of the Content-Disposition header
.fileName("fileName")
// defaults to "form-data"
.dispositionType("dispositionType")
.contentId("contentId")
.transferEncoding("transferEncoding")
.header("name", "value")
)
StringBodyPart
类似于 StringBody。
RawFileBodyPart
其中 path 是将按原样上传的文件的位置。
类似于 RawFileBody。
ElFileBodyPart
其中 path 是将使用 Gatling EL 引擎解析和解析其内容的文件的位置。
类似于 ElFileBody。
PebbleStringBodyPart
类似于PebbleStringBody
PebbleFileBodyPart
类似于PebbleFileBody
ByteArrayBodyPart
类似于ByteArrayBody
processRequestBody
您可能希望在将请求正文发送到网络之前对其进行处理。 Gatling currenlty 只提供了一个预处理器:gzipBody。
http("name").post("/")
.body(RawFileBody("file"))
.processRequestBody(gzipBody)
Gatling 可以并行获取主请求的资源,以模拟真实 Web 浏览器的行为。
http("name").get("/")
.resources(
http("api.js").get("/assets/api.js"),
http("ga.js").get("/ga.js")
)
requestTimeout
默认请求超时由 ``gatling.http.requestTimeout` 配置参数控制。
但是,您可能希望使用 requestTimeout 覆盖特定请求的全局值,通常是长文件上传或下载。
http("name").get("/")
.requestTimeout(3.minutes)
basicAuth
和 digestAuth
就像您可以在 HttpProtocol 配置上定义全局 basicAuth 或 digestAuth 一样,您可以在单个请求上定义一个。
proxy
就像您可以在 HttpProtocol 配置上全局定义一个代理一样,您也可以在单个请求上定义一个。
virtualHost
就像您可以在 HttpProtocol 配置上全局定义一个虚拟主机一样,您可以在单个请求上定义一个。
disableFollowRedirect
就像您可以在 HttpProtocol 配置上全局禁用以下重定向一样,您可以在单个请求上定义一个。
disableUrlEncoding
就像您可以在 HttpProtocol 配置上全局禁用 URL 编码一样,您可以在单个请求上定义一个。
silent
有关详细信息,请参阅沉默协议部分。
然后,您可以使请求静默:
http("name").get("/")
.silent
您可能还希望执行完全相反的操作,通常是在给定资源上,而资源已在协议级别全局变为静默:
.resources(
http("resource").get("/assets/images/img1.png")
.notSilent
)
sign
就像您可以在 HttpProtocol 配置上定义全局签名策略一样,您也可以在单个请求上定义一个。
transformResponse
同样,人们可能希望在将响应传递到检查管道之前对其进行处理:
transformResponse(responseTransformer: (Response, Session) => Validation[Response])
下面的例子展示了如何解码一些 Base64 编码的响应体:
import java.nio.charset.StandardCharsets.UTF_8
import java.util.Base64
import io.gatling.http.response._
// ignore when response status code is not 200
.transformResponse {
(response, session) =>
if (response.status.code == 200) {
response.copy(body = new ByteArrayResponseBody(Base64.getDecoder.decode(response.body.string), UTF_8))
} else {
response
}
}