当前位置: 首页 > 工具软件 > Gatling > 使用案例 >

Gatling:HTTP Request

微生嘉
2023-12-01

目录

请求名称

Method和URL

Query Parameters

Headers 

header

asXXX

检查

Request Body

StringBody

RawFileBody

ElFileBody 

PebbleStringBody

PebbleFileBody 

ByteArrayBody

InputStreamBody

Forms

formParam

form

formUpload

Multipart

bodyPart

StringBodyPart

RawFileBodyPart

ElFileBodyPart

PebbleStringBodyPart

PebbleFileBodyPart

ByteArrayBodyPart

Pre-Processing

processRequestBody

Resources

高级选项

requestTimeout

basicAuth 和 digestAuth

proxy

virtualHost

disableFollowRedirect

disableUrlEncoding

silent

sign

transformResponse


了解 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)

 

Method和URL

        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。
 

Query Parameters

        框架和开发人员经常在查询中传递附加信息,即 url 后面的部分。 查询由键=值对组成,用 & 分隔。 这些是命名的查询参数。
例如,https://github.com/gatling/gatling/issues?milestone=1&state=open 包含 2 个查询参数:

  • milestone=1 :参数名是milestone, 参数值是1
  • state=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"))

Headers 

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

 

Request Body

在本节中,您可以找到设置完整请求正文的各种方法。
正文模板位置的解析方式与 Feeder 文件相同。文件必须放在:

  • 使用捆绑分发时的user-files/resources目录
  • src/main/resources 或 src/test/resources(使用 maven、gradle 或 sbt 项目时)

不要使用相对文件系统路径,例如 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 允许您传递一个原始文件,其字节将按原样发送,这意味着它可以是二进制内容。 这种方式是最有效的方式,因为字节可以被缓存,而不必解码为文本,然后重新编码回字节以写入网络。
它需要一个参数:

  • filePath 文件位置,可以是纯字符串、gatling表达式语言字符串或函数。
// 静态路径
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 表达式语言格式的模板文件解析的文本内容。
它需要一个参数:

  • filePath 文件位置,可以是纯字符串、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))))

 

Forms

本节指的是使用 application/x-www-form-urlencodedmultipart/form-data 编码的有效负载,用于 HTML 表单。
除非您明确设置 Content-Type:

  • 如果您设置了至少一个file part,Gatling 会将其设置为 multipart/form-data
  • 否则,它会将其设置为 application/x-www-form-urlencoded。

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 个参数:

  • name 表单输入的名称,可以是纯字符串、gatling表达式语言字符串或函数。
  • filePath 文件的路径,可以是纯字符串、加特林表达式语言字符串或函数。

见上文 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)。 在需要时覆盖它们。

 

Multipart
 

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

Pre-Processing

processRequestBody

您可能希望在将请求正文发送到网络之前对其进行处理。 Gatling currenlty 只提供了一个预处理器:gzipBody。

http("name").post("/")
  .body(RawFileBody("file"))
  .processRequestBody(gzipBody)

 

Resources

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
    }
}

 类似资料:

相关阅读

相关文章

相关问答