Gatling的queryParam、formParam和multipartFormData是构建HTTP请求参数的三种主要方式,分别对应不同的协议标准和数据格式。
1. queryParam:构建URL查询字符串
queryParam 用于构建URL中的查询字符串(?key1=value1&key2=value2),主要应用于GET请求,也可用于POST、PUT等。
基础和动态用法
scala
import io.gatling.core.Predef._
import io.gatling.http.Predef._
// 基础静态参数
http("基础查询请求")
.get("/api/search")
.queryParam("category", "books") // ?category=books
.queryParam("sort", "price_desc")
// 动态参数(从Session中提取)
.exec(
http("动态查询请求")
.get("/api/search")
.queryParam("userId", "${userId}") // EL表达式引用Session变量
.queryParam("page", "${currentPage}")
.queryParam("query", "#{randomString(10)}") // 使用Gatling内置函数
)
高级用法-参数列表和条件参数
scala
// 构建多值参数(数组)
.queryParam("tags", "java,scala,performance") // 方式1:逗号分隔
.queryParam("tags", Seq("java", "scala", "performance")) // 方式2:Scala序列
// 条件性添加参数
.exec(session => {
val userLevel = session("userLevel").as[String]
val params = if (userLevel == "vip") {
Map("vip_only" -> "true", "premium" -> "yes")
} else {
Map("standard" -> "true")
}
session.set("queryParams", params)
})
.exec(
http("条件查询")
.get("/api/content")
.queryParam("basic", "always")
// 动态添加多个参数
.queryParamList("#{queryParams}")
)
2. formParam-标准表单编码
formParam 用于 application/x-www-form-urlencoded 格式,这是HTML表单的默认提交格式。
基础和批量提交
scala
// 基础表单提交(模拟登录)
http("用户登录")
.post("/login")
.header("Content-Type", "application/x-www-form-urlencoded")
.formParam("username", "${username}")
.formParam("password", "${password}")
.formParam("remember_me", "true")
// 批量添加参数(适用于参数数量动态变化)
.exec(session => {
val formData = Map(
"name" -> "测试用户",
"email" -> "test@zmtests.com",
"age" -> "30",
"subscription" -> "premium"
)
session.set("formDataMap", formData)
})
.exec(
http("批量表单提交")
.post("/profile/update")
.formParamList("#{formDataMap}") // 批量添加所有参数
)
编码和特殊字符处理
scala
// Gatling自动进行URL编码,但需注意特殊情况
.formParam("search_query", "Gatling & Performance Testing")
// 编码为:Gatling%20%26%20Performance%20Testing
// 处理已编码值(使用原始字符串)
.formParam("pre_encoded", RawFileBodyPart("已编码的数据.txt"))
// 或手动控制编码
.exec(session => {
val rawValue = "特殊&字符=测试"
val encodedValue = java.net.URLEncoder.encode(rawValue, "UTF-8")
session.set("safeValue", encodedValue)
})
3. multipartFormData-混合表单数据(含文件上传)
multipartFormData 用于 multipart/form-data 格式,支持混合文本字段和二进制文件上传。
基础文件上传
scala
// 基本文件上传(小文件)
http("上传单文件")
.post("/upload")
.bodyPart(RawFileBodyPart("file", "test.pdf")) // 从resources文件夹读取
.bodyPart(StringBodyPart("description", "性能测试报告PDF文档"))
// 指定MIME类型和字符集
http("上传带元数据的文件")
.post("/upload")
.bodyPart(
RawFileBodyPart("document", "report.pdf")
.contentType("application/pdf") // 指定MIME类型
.fileName("性能报告.pdf") // 自定义客户端文件名
)
.bodyPart(
StringBodyPart("notes", "这是最终版本的报告")
.charset("UTF-8") // 指定字符集
)
高级用法-动态多文件和流式处理
scala
// 动态构建多文件上传
val fileFeeder = csv("test_files.csv").random // 从CSV文件获取文件信息
exec(feed(fileFeeder))
.exec(
http("动态多文件上传")
.post("/batch-upload")
.bodyPart(RawFileBodyPart("file1", "${file1_path}"))
.bodyPart(StringBodyPart("category1", "${file1_category}"))
.bodyPart(RawFileBodyPart("file2", "${file2_path}"))
.bodyPart(StringBodyPart("category2", "${file2_category}"))
.bodyPart(StringBodyPart("uploader", "${userId}"))
)
// 大文件处理和流式上传(避免内存溢出)
http("流式上传大文件")
.post("/upload-large")
.processRequestBody(
bodyParts =>
bodyParts.map {
case part: RawFileBodyPart => part.toStream // 转换为流处理
case other => other
}
)
.bodyPart(
RawFileBodyPart("video", "large_video.mp4")
.contentType("video/mp4")
.transferEncoding("binary") // 二进制传输编码
)
.bodyPart(StringBodyPart("comment", "大文件测试"))
内存优化和性能配置
scala
// Gatling配置中调整multipart相关参数
val httpProtocol = http
.baseUrl("http://zmtests.com")
.multipartBoundary("----WebKitFormBoundaryABC123") // 自定义边界
.disableWarmUp // 对于大文件测试,禁用热身以减少内存波动
.shareConnections // 共享连接提高效率
// 在具体请求中控制缓冲区大小
http("优化文件上传")
.post("/upload")
.bodyPart(
RawFileBodyPart("data", "large.bin")
.contentType("application/octet-stream")
)
.requestTimeout(60000) // 增加超时时间
注意事项
参数编码一致:Gatling自动处理URL编码,保证测试数据和实际生产数据编码一致
Session变量管理:对于动态参数,合理使用Session来存储和管理参数状态
文件资源管理:
scala
// 使用feeder动态选择文件
val fileFeeder = Iterator.continually(Map(
"filePath" -> s"data/test_${java.util.UUID.randomUUID().toString}.txt"
))
// 测试后清理生成的文件
after {
println("测试完成,清理临时文件")
// 文件清理逻辑
}
性能监控:
queryParam:注意URL长度和参数解析
formParam:注意编码/解码CPU消耗
multipartFormData:注意内存使用、I/O吞吐和网络延迟
调试
scala
// 1. 打印实际请求详情
.exec { session =>
// 通过日志或调试器查看实际构建的请求
println(s"请求参数: ${session("requestParams").asOption[String]}")
session
}
// 2. 使用Gatling HTTP日志
val httpProtocol = http
.baseUrl("http://zmtests.com")
.enableHttp2
.disableCaching
.silentResources // 静默资源请求
.silentUri(".*\\.(css|js|png|gif).*")
.disableFollowRedirect
.maxConnectionsPerHost(10)
.acceptHeader("*/*")
.userAgentHeader("Gatling/3.0")
.warmUp("http://zmtests.com/health") // 预热
.check(status.is(200)) // 基础检查
这三种参数构建方式能精准模拟从简单查询到复杂文件上传的各种实际业务情形。