在Gatling中构建JSON请求体,StringBody、ElFileBody和Pebble模板是三种主要且逐级进阶的方式,分别用于不同复杂度、灵活性和维护性需求的情形。
1. StringBody:直接和动态字符串构建
StringBody是最直接的方式,适合请求体简单或轻量动态化的情形。
纯静态JSON:直接写入JSON字符串。
scala
.body(StringBody("""{"username": "testUser", "status": 1}"""))
嵌入动态EL表达式:利用Gatling的EL(表达式语言)在字符串中引用Session变量、函数或属性,实现动态化。变量名需用 ${} 包裹。
scala
.exec(
session => session.set("userId", 1001) // 设置Session变量
)
.exec(
http("Create User")
.post("/users")
.body(StringBody(
"""{
"id": ${userId}, // 引用Session变量
"name": "user_#{java.util.UUID.randomUUID()}", // 调用函数生成随机名
"createdAt": "#{new java.util.Date().getTime()}" // 调用函数生成时间戳
}"""
))
)
性能提示:StringBody 在每次请求时都会解析字符串中的EL表达式。对于高频请求,如果表达式复杂或计算成本高,就需要注意性能开销。
2. ElFileBody:基于外部文件的模板创建
ElFileBody 将JSON结构存储在外部文件中,实现了数据和脚本的分离,便于维护复杂或大型的请求体。
创建模板文件:在Gatling项目的 resources 目录(或其它已配置的类路径)下创建 .json 或 .txt 文件,如 templates/create-user.json。
在文件中使用EL占位符:
json
{
"id": "${userId}",
"name": "${userName}",
"email": "user_${userId}@example.com",
"preferences": {
"newsletter": ${subscribeNewsletter},
"language": "${language}"
}
}
重要规则:在 ElFileBody 中,EL表达式必须使用 ${} 格式,且默认不支持 #{function} 函数调用语法。如需在文件模板中调用函数,需在配置中启用。
在脚本中引用文件:使用相对类路径引用模板文件。
scala
.exec(
http("Create User from File")
.post("/users")
.body(ElFileBody("templates/create-user.json"))
)
为保持最佳性能,Gatling默认缓存文件内容。这意味着模板文件在测试启动时被读取并常驻内存,避免了每次请求的磁盘I/O开销。因此对于需要动态内容的情形,应使用EL表达式而非直接修改文件。
3. Pebble模板引擎:高级逻辑和复杂结构创建
当JSON结构需要条件判断、循环迭代、模板继承或包含等高级逻辑时,Pebble模板引擎是比EL表达式更强大的选择。
启用和配置Pebble:在Gatling配置中启用Pebble支持。
scala
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.pebble.PebbleSupport // 导入支持
val pebbleSupport = new PebbleSupport // 创建支持实例
使用Pebble语法编写模板:创建 .peb 文件(例如 complex-user.peb)。
json
{
"users": [
{% for userId in userIds %}
{
"id": {{ userId }},
"name": "User_{{ userId }}",
"isActive": {% if userId % 2 == 0 %}true{% else %}false{% endif %}
}{% if not loop.last %},{% endif %} {# 循环内逗号控制 #}
{% endfor %}
],
"metadata": {
"count": {{ userIds.size }},
"generatedAt": "{{ timestamp }}"
}
}
在脚本中传递数据并使用模板:通过Session或Map向Pebble模板传递数据。
scala
.exec(
session => {
// 构建传递给Pebble的数据模型
val dataModel = Map(
"userIds" -> List(1001, 1002, 1003, 1004),
"timestamp" -> System.currentTimeMillis.toString
)
session.set("pebbleData", dataModel)
}
)
.exec(
http("Complex Create Users")
.post("/users/batch")
// 使用PebbleBody加载模板并传入数据模型
.body(pebbleSupport.PebbleBody("templates/complex-user.peb", "#{pebbleData}"))
)
注意:PebbleBody 的第二个参数接收一个EL表达式(#{pebbleData}),应从Session中解析出传递给Pebble的数据模型Map。