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

相关推荐
天才测试猿5 小时前
Jmeter命令行压测&生成HTML测试报告
软件测试·测试工具·jmeter·职场和发展·jenkins·测试用例·压力测试
@Dream-fennel5 小时前
WebSocket教程:如何使用JMeter进行压力测试
websocket·jmeter·压力测试
Ronin3055 小时前
【Linux网络】NAT、代理服务、内网穿透
linux·网络·智能路由器·内网穿透·nat·代理服务器·内网打洞
程序员三藏5 小时前
Jmeter的三种参数化方式
自动化测试·软件测试·python·测试工具·jmeter·测试用例·压力测试
feathered-feathered5 小时前
网络套接字——Socket网络编程(TCP编程详解)
java·网络·后端·网络协议·tcp/ip
测试人社区—66796 小时前
破茧成蝶:DevOps流水线测试环节的效能跃迁之路
运维·人工智能·学习·flutter·ui·自动化·devops
秋刀鱼 ..7 小时前
第七届国际科技创新学术交流大会暨机械工程与自动化国际学术会议(MEA 2025)
运维·人工智能·python·科技·机器人·自动化
盐焗西兰花9 小时前
鸿蒙学习实战之路 - 网络重连最佳实践
网络·学习·harmonyos