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测试场景的关键,从简单场景开始,再慢慢增加并发和业务逻辑复杂度。

相关推荐
安全渗透Hacker2 小时前
新一代特征扫描器afrog与经典引擎Xray深度解析
网络·安全·web安全·网络安全·自动化·系统安全·安全性测试
Xの哲學2 小时前
Linux IPC机制深度剖析:从设计哲学到内核实现
linux·服务器·网络·算法·边缘计算
may_一一3 小时前
selenium自动化调用接口为null问题处理
selenium·测试工具·自动化
代码游侠3 小时前
应用——Linux Socket编程
运维·服务器·开发语言·笔记·网络协议·学习
幺零九零零3 小时前
Docker底层-Namespaces(网络隔离)
网络·docker·容器
代码游侠3 小时前
学习笔记——sqlite3 数据库基础
linux·运维·网络·数据库·笔记·学习·sqlite
Ronin3053 小时前
多路转接epoll
linux·网络·多路转接·高效io·epoll模型
AI前端老薛3 小时前
HTTP和HTTPS的区别
网络协议·http·https