Gatling WebSocket测试支持:ws、wsConnect、sendText、checkTextMessage详解

Gatling进行WebSocket测试是模拟从建立连接、收发消息到验证响应的完整长连接会话。

ws和connect

ws("操作名称") 用于创建一个 WebSocket 操作构建器。本身不建立连接,是后续 connect、sendText 等具体操作的开始,参数用于在报告中标识该操作。

真正的连接建立由 .connect("/path") 方法完成。它向配置的wsBaseUrl发起HTTP握手并升级为WebSocket连接。

建立连接通常有两种方式,带参数基础连接和命名连接。

基础连接和参数传递

这是最常见的方式,通常在scenario中直接使用。你可以通过查询字符串传递动态参数,这些参数可以来自会话(Session)。

Scala 复制代码
.exec(

    ws("建立聊天连接")

      .connect("/chat?username=#{username}&token=#{authToken}")

)

命名连接

对于需要跨多个请求复用同一个物理连接,或在同一场景中管理多个并行 WebSocket 连接的复杂场景,可以使用命名连接。

通过 .wsName("connectionName") 为连接指定一个名称,后续操作通过同名ws引用该连接。

Scala 复制代码
// 建立命名连接

.exec(ws("Connect", "myWs").connect("/socket"))

// 使用同一连接发送消息

.exec(ws("Send on myWs", "myWs").sendText("..."))

发送消息:sendText

.sendText("消息内容") 用于通过已建立的 WebSocket 连接向服务器发送文本消息。消息内容可以是静态字符串,也可以利用Gatling的EL(表达式语言)语法 #{variableName} 从会话中动态获取,从而模拟真实用户行为。

Scala 复制代码
.exec(

    ws("发送聊天消息")

      .sendText("""{"type": "chat", "content": "Hello, I'm #{userId}!"}""")

)

验证响应:checkTextMessage和await

服务器返回的消息不会自动触发断言,必须使用check来验证。这是Gatling WebSocket测试中最重要的一步,用来确认系统行为是否正确。

主要模式是 "发送后等待并检查",通过 .await(timeout) 方法实现。

定义检查点

使用 ws.checkTextMessage("检查点名称") 创建一个针对文本消息的检查器,后接 .check() 方法定义具体的断言规则(如检查 JSON 路径、正则表达式等)。

Scala 复制代码
val messageCheck = ws.checkTextMessage("验证服务端回复")

    .check(

        jsonPath("$.reply").is("Hello back!"),

        jsonPath("$.status").saveAs("msgStatus") // 将值保存到会话,供后续使用

    )

等待并执行检查

在sendText后链式调用 .await(timeout)(check1, check2...)。Gatling 会等待最多timeout时长,尝试将在此期间收到的下一条服务器消息和定义的检查点进行匹配。

Scala 复制代码
.exec(

    ws("发送并等待回复")

      .sendText("""{"command": "ping"}""")

      .await(5.seconds)(messageCheck) // 等待5秒内匹配 messageCheck

)

提示:checkTextMessage 的API在 Gatling 3.0 后发生了变化。在旧版本(如 2.3)中,check 方法可以直接链式调用在sendText之后,但新版本中必须使用await块来包裹检查。

协议的配置

要稳定地进行测试,需要在协议层面进行基础配置。

基础协议配置

HttpProtocol使用 .wsBaseUrl("ws://host:port") 设置WebSocket服务的基础地址。还可以配置重连策略、自动回复心跳等。

Scala 复制代码
val httpProtocol = http

    .baseUrl("http://localhost:8080")

    .wsBaseUrl("ws://localhost:8080")

    .wsReconnect // 启用自动重连

    .wsMaxReconnects(3) // 最大重连次数

    .wsAutoReplyTextFrame { // 自动回复特定心跳消息

        case "ping" => "pong"

    }

高并发和长连接

资源管理:WebSocket 是长连接,高并发下会长期占用文件描述符和内存。需监控测试客户端和服务器端的资源限制。

负载模型:对于连接保持时间长、消息发送间歇性强的场景(如聊天),使用 constantConcurrentUsers 或 rampConcurrentUsers 来模拟稳定的并发用户池,比单纯使用 rampUsers 更真实。

综合应用例子

下面的脚本综合了上述所有操作,模拟了一个简单的 WebSocket 聊天室用户行为:

Scala 复制代码
import io.gatling.core.Predef._

import io.gatling.http.Predef._

import scala.concurrent.duration._



class WebSocketChatSimulation extends Simulation {



    val httpProtocol = http

        .wsBaseUrl("ws://localhost:9000")

        .wsAutoReplyTextFrame { case "ping" => "pong" }



    // 定义一个检查点,用于验证连接成功后服务器返回的欢迎消息

    val connectCheck = ws.checkTextMessage("连接确认")

        .check(jsonPath("$.msg").is("Welcome to chat!"))



    // 定义一个检查点,用于捕获其他用户发送的聊天消息

    val incomingMessageCheck = ws.checkTextMessage("新消息")

        .check(jsonPath("$.from").saveAs("sender"),

               jsonPath("$.text").saveAs("messageText"))



    val scn = scenario("WebSocket Chat User")

        .exec(http("获取凭证").get("/auth").check(jsonPath("$.token").saveAs("userToken")))

        .pause(1)

        // 1. 建立连接

        .exec(ws("连接聊天室").connect("/chat?token=#{userToken}").await(2.seconds)(connectCheck))

        .pause(1)

        // 2. 发送第一条消息并等待回显

        .exec(ws("发送问候语")

            .sendText("""{"text": "大家好,我上线了!"}""")

            .await(5.seconds)(

                ws.checkTextMessage("回显检查").check(jsonPath("$.echo").exists)

            ))

        // 3. 模拟循环:间歇性发送消息,并同时监听服务器推送的其他消息

        .repeat(5) {

            pause(3.seconds)

            .exec(ws("发送随机消息").sendText("""{"text": "Current time is #{currentTime}"}"""))

            // 此处的await会等待本次sendText的特定回复

            .pause(2.seconds)

            // 这个单独的await用于监听期间可能收到的其他消息(如别人发的)

            .exec(ws("监听广播").await(3.seconds)(incomingMessageCheck))

        }

        // 4. 关闭连接

        .exec(ws("断开连接").close)


    setUp(
        scn.inject(rampUsers(100).during(30.seconds))
    ).protocols(httpProtocol)

}

掌握 Gatling的ws/connect、sendText 和 checkTextMessage/await 的组合使用,是搭建Gatling WebSocket测试场景的关键,从简单场景开始,再慢慢增加并发和业务逻辑复杂度。

相关推荐
2601_962293243 小时前
Python自动化统计团队工作量并生成可视化仪表盘的脚本方案【指导】
python·数据分析·自动化·可视化·仪表盘
啊阿狸不会拉杆3 小时前
《计算机网络-自顶向下方法》5.4 ISP之间的路由选择:BGP 读书笔记
网络·计算机网络·接口隔离原则
2601_962293794 小时前
OCRmyPDF批处理脚本:使用Python自动化复杂OCR任务
python·自动化·批处理脚本·ocrmypdf·ocr任务
Delite8025 小时前
摆脱实验室束缚:便携式卡尔费休微量水分检测技术与现场应用解析
大数据·网络·人工智能
ACP广源盛139246256735 小时前
M6/M5 Pro Mac mini 端侧 AI 落地@ACP#YLB3116 中端多盘存储扩展在 AI 服务中的机会与应用场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos
明月_清风5 小时前
MCP vs ACP vs LSP:AI 时代三大协议的「三足鼎立」
人工智能·网络协议·agent
ACP广源盛139246256736 小时前
M6/M5 Pro Mac mini 端侧 AI 新形态@ACP#GSV5800 Serdes 长距离视频传输在 AI 服务中的机会与落地场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos·音视频
我爱cope6 小时前
【计算机网络 | 传输层3:TCP 协议概述:面向连接、可靠传输到底意味着什么?】
网络·网络协议·学习·tcp/ip·计算机网络·传输层
OIDCAT7 小时前
国产USB转千兆网卡芯片CH398-RTL8153国产替代实测与选型
网络·嵌入式硬件·智能硬件·国产芯片·usb转千兆网卡