
做接口测试这些年大家习惯用 Postman 跑 HTTP一遇到 WebSocket 接口就不知道该拿什么工具。其实 Postman 早就原生支持 WebSocket 接口调试了只是很多人不知道或者试过一次说不好使就放弃了。WebSocket 和 HTTP 最大的不同是它一旦建立连接服务器就能主动往你这边推数据这也意味着它的测试关注点从请求-响应变成了连接-消息-事件。用 Postman 测 WebSocket 接口能帮你在不写代码的情况下完成建连、发消息、收消息、看原始帧、验心跳这一整套动作。这篇文章适合正在接实时推送、聊天、行情或者物联网服务的同学也适合想补全接口测试技能树的测试工程师。1. 为什么用 Postman 来测 WebSocket 接口1.1 WebSocket 接口测试到底在测什么先明确一个容易混淆的点WebSocket 接口不是一个简单的 URL 发过去然后返回一个 JSON它是一个有状态的通道。HTTP 接口可以理解成去柜台办业务办完就走WebSocket 则是办完业务后你和柜台之间开了一条专用电话线柜员后续会主动打电话告诉你进度。所以测 WebSocket 接口时重点不再只是入参对不对、响应对不对而是下面这几个维度握手是否成功。客户端发一个带有 Upgrade 头的 HTTP 请求服务端必须返回 101 Switching Protocols连接才真正建立。消息能不能双向收发。服务端能不能收到客户端的消息客户端能不能收到服务端的推送。连接能不能保持。长连接需要保活机制有协议层的心跳帧也有应用层自定义的心跳消息。异常场景处理。网络断掉、服务端重启、消息体超长、鉴权过期这些都会导致连接状态变化。关闭行为是否规范。WebSocket 有专门的关闭帧里面带着状态码比如 1000 是正常关闭1006 是异常关闭。我用 Postman 测过大量实际项目最大的感受是它能帮你在十分钟内把能不能连通这个问题定性。如果 Postman 都连不上基本可以排除客户端代码问题往后端一丢就完事了。1.2 Postman 在 WebSocket 测试里的定位Postman 不是万能的。它适合做功能验证、接口联调、问题复现但不适合做高并发压力测试也不适合做复杂的协议自动化断言。在实际工作中我的分工通常是Postman 负责日常调试和快速验证JMeter 或者脚本负责压测Wireshark 负责深挖底层网络问题。还有一个特别实用的点Postman 的请求可以保存到 Collection 里带上环境变量、Header、示例消息整个团队都能看到。后端同事给了新地址、改了个鉴权方式直接改环境变量就行。这样一来WebSocket 接口的联调记录就沉淀下来了不会出现人走方案失传的情况。2. 准备工作把 Postman 调到 WebSocket 测试模式2.1 版本确认与入口Postman 从 v9.6 开始原生支持 WebSocket 请求我建议直接用最新版。如果你打开界面找不到 WebSocket 入口大概率是版本太老去官网更新一下就好。创建 WebSocket 请求的方式和创建 HTTP 请求非常像。点左上角 New 按钮弹出的选项里能看到 WebSocket Request或者点顶部标签栏旁边的号打开新标签页再点请求类型切换的下拉菜单选择 WebSocket。老版本可能在新建界面里需要往下翻一点才能看到第一次找确实有点隐蔽。我个人习惯直接点新开标签页然后在新标签页的 URL 输入框后面看到一个小图标或下拉按钮切换到 WebSocket。不同版本的 UI 位置不一样但核心流程都一样新建 WebSocket Request填入地址点 Connect。2.2 URL、Headers、Params 的正确填法WebSocket 的 URL 分两种ws://和wss://。在测试环境里用ws://比较多就是明文传输生产环境一般用wss://实际是 TLS 加密的 WebSocket注意如果服务端证书有问题连接会失败。URL 里可以带路径和查询参数比如ws://127.0.0.1:8080/chat?roomId1024tokenabc123路径在 WebSocket 服务里非常重要。很多同学连接失败是因为只写了域名没写路径比如/ws/chat是业务入口结果ws://xx:8080/连过去什么都没回。Postman 的 URL 输入框和 HTTP 请求一样支持环境变量比如wss://{{host}}/ws/chat这样切换环境就非常方便。Headers 和 Params 这两个区域容易混淆。Params 是拼在 URL 后面作为查询字符串的适合放房间号、连接模式、渠道标识这类较轻的参数。Headers 适合放Authorization、Origin、Cookie等连接鉴权信息。WebSocket 握手本质上是一次 HTTP 请求所以 Header 里带上普通 HTTP 请求能用的东西大多都能生效。2.3 鉴权与 Cookie 的常见处理我在实际项目中遇到最多的 WebSocket 连接失败不是协议问题而是鉴权没过。Postman 里处理鉴权有几种常见方式请求头里加Authorization: Bearer token。加自定义头比如有些后端要求X-Auth-Token。加Cookie比如Cookie: session_idxxxx。URL 参数里带签名比如ws://host/ws?signmd5(...)。这些内容都支持环境变量。强烈建议把 token 放到环境变量里而不是每次手动粘贴。因为环境变量可以被同一个环境下的所有请求共用后端如果更新了 token你只需要在 Postman 的 Environment 管理里改一次。另一个常见问题是 token 过期。HTTP 接口测试的时候 Postman 可以通过脚本自动刷新 tokenWebSocket 请求的脚本机制在部分版本里也能用但为了稳定起见我一般直接先手动在浏览器里登录一次拿到新 token 更新到环境变量再重新 Connect。别嫌麻烦这个流程能省下后面很多排查时间。2.4 用本地模拟服务快速上手如果手头没有现成的 WebSocket 服务我建议本地起一个最小服务来熟悉流程。这样不依赖外部网络也不会把测试数据打到公网服务上。用 Node.js 配合 ws 库几十行代码就能搞定。先安装 ws 模块npm init -y npm install ws然后写一个服务端脚本 server.jsconst WebSocket require(ws); const wss new WebSocket.Server({ port: 8080 }); wss.on(connection, function connection(ws, req) { console.log(客户端已连接路径:, req.url); ws.on(message, function incoming(data) { const text data.toString(); console.log(收到消息:, text); ws.send(服务端收到: text); }); ws.send(欢迎连接本地 WebSocket 服务); });启动服务node server.js这样 Postman 里直接填ws://127.0.0.1:8080点击 Connect就能看到服务端打印连接日志随后客户端会收到欢迎连接的消息。整个环境干净可控非常适合练手。3. 手把手完成一次 WebSocket 接口调试3.1 第一步建连与握手把 URL 填成ws://127.0.0.1:8080先不急着加 Headers点一下 Connect。如果连接成功按钮区域会出现 Connected 状态下方消息列表里会多一条服务端主动推送的欢迎消息。这一瞬间实际上发生了这样的事Postman 给服务端发了一个带着Upgrade: websocket和Connection: Upgrade头的 HTTP 请求服务端校验通过后返回 101 Switching Protocols然后两边进入 WebSocket 数据帧通信。Postman 界面上不会把这个 101 响应直接显示出来但连接成功的状态就代表握手已经通过了。如果握手失败Postman 通常会给出错误提示比如 403、404、401这些其实就是握手阶段 HTTP 状态码。可以简单理解成服务端在切换协议之前先用普通 HTTP 的逻辑把你的连接请求审核了一遍审核没过就直接拒绝。3.2 第二步发送一条文本消息连接建好之后中间那块消息输入框就可以用了。比如填{type:ping,content:hello}点 Send 或直接按回车这条消息会以 Outgoing 的标识出现在消息列表里。本地模拟服务收到后马上回一条 服务端收到: ... 的消息消息列表里会以 Incoming 标识展示。这一步能验证最基本的双向通信。我建议把发送消息的类型和内容都规范起来最好使用 JSON 字符串。很多 WebSocket 接口的消息体就是 JSONPostman 的消息输入框支持语法高亮粘贴后能直接看到有没有格式错误。如果填的 JSON 有问题点 Send 之前就能看出来避免把错误的格式发给后端。3.3 第三步观察返回与确认帧格式在 Postman 的消息列表里每条消息都带有方向、时间和内容。单击一条消息能看到更详细的信息有的版本还支持按文本、JSON、二进制等格式切换显示。这里我踩过一次坑服务端推送的消息在 Postman 里显示一堆乱码我当时以为协议有问题后来才发现服务端发的是二进制帧Postman 默认按文本去解码自然看不出来。遇到乱码时先别急着甩锅看一眼消息列表里这条消息的类型标注如果是 Binary就按二进制帧去处理或者让后端临时输出一份文本日志来对比。文本帧和二进制帧是两种不同的 WebSocket 帧类型。文本帧里放的是 UTF-8 字符串二进制帧里放的是字节流适合图片、protobuf、加密数据等。Postman 对文本帧的处理非常友好对二进制帧的支持相对有限日常调试文本协议完全够用。3.4 第四步使用变量保存动态数据WebSocket 请求同样支持 Postman 的环境变量和全局变量。比如在一个多租户项目里不同租户的 WebSocket 地址不一样你可以把地址维护成ws://{{host}}/ws?tenantId{{tenantId}}切换环境的时候地址自动变化。消息输入框里也支持变量替换。比如我经常把服务端返回里拿到的一个会话 ID 存到环境变量然后在后续消息里引用它。操作路径是在消息列表或脚本里通过变量函数取值把值保存到环境变量然后在 Message 输入框写{{sessionId}}。这套方式和 HTTP 请求的变量使用逻辑完全一致团队协作时特别省心。需要提醒的是变量替换发生在消息发送之前。如果你发现 Postman 原样把{{sessionId}}字符串发出去了基本说明这个变量名在当前环境里不存在。检查右上角环境选择器是不是选对了再确认变量名拼写有没有问题。3.5 第五步把请求保存成定期回归用例Postman 最大的价值不是单次调试而是沉淀。建连好、消息验证通过之后点保存按钮把这个 WebSocket 请求存到 Collection 里写上接口名、业务说明、使用到的环境变量和典型的消息体让后来的人直接打开就能用。但要说清楚WebSocket 请求不能像 HTTP 请求那样用 Collection Runner 全自动跑完因为长连接消息的到达时机是不确定的。我一般把它作为联调手册保存下来后端迭代完让接口人自己用 Postman 点一遍而不是指望 CI 全自动回归。想自动化得走脚本或专门的压力工具。4. 需要重点关注的协议细节与坑4.1 握手顺序为什么能拿到 HTTP 101WebSocket 的建连过程可以拆成三句话客户端发 HTTP Upgrade 请求服务端确认并返回 101双方开始收发数据帧。这个机制决定了 WebSocket 接口天然继承了 HTTP 层的一些特性比如 Header、Cookie、状态码。测试的时候要特别注意如果服务端返回的不是 101而是普通的 200说明它把连接请求当普通 HTTP 请求处理了根本没打算升级协议。常见原因是服务端路由没匹配到 WebSocket 处理器或者部署网关没有放行 Upgrade 请求。这类问题在 Postman 里通常直接显示连接失败但日志里能看到Unexpected server response: 200这个信息非常关键。还有一种情况是中间加了负载均衡或网关如果超时时间设置太短或者配置里没开启 WebSocket 支持握手请求可能被拦掉。用 Postman 测的时候如果反复握手超时可以把地址换成直连测试环境的 IP 试试排除中间链路干扰。4.2 子协议Subprotocol的选择有些 WebSocket 服务要求客户端指定子协议通过Sec-WebSocket-Protocol这个 Header 来协商。比如 GraphQL 的graphql-ws、MQTT over WebSocket 的mqtt以及一些内部自定义协议。Postman 不会主动帮你加这个 Header需要自己在 Headers 区域手动加。我第一次测一个 GraphQL 订阅接口时就忘了加子协议服务端一直返回 400排查很久才发现是缺了Sec-WebSocket-Protocol: graphql-ws。如果服务端要求多个子协议中的一个Wildcard 是不行的得明确写一个。通常后端文档会写清楚支持哪些子协议直接填就行。测试时如果连上了又立刻被断开也可以检查一下子协议是否匹配。4.3 心跳保活机制怎么验WebSocket 长连接如果长时间没有消息中间网络设备可能会把空闲连接断开。为了避免这种情况协议层和应用层都会有心跳机制。协议层的心跳是 Ping 帧和 Pong 帧WebSocket 规范规定收到 Ping 必须回 Pong这个通常由客户端底层自动完成Postman 作为客户端也会自动处理所以你在消息列表里不一定能直接看到。更常见的是应用层心跳比如服务端每 30 秒推送一条{type:heartbeat}客户端收到后回一条{type:heartbeat_ack}。这种心跳消息本质上就是普通业务消息Postman 完全可以模拟。方法很简单连接建立后在 Message 框里写好心跳消息隔一段时间手动点一次观察连接状态是否一直保持。我建议在用 Postman 调试阶段先检查一下服务端的心跳间隔配置。如果心跳间隔很短而 Postman 这边没有自动发送机制你需要手动发送或者开启脚本循环发送。部分新版本 Postman 的 WebSocket 请求脚本区域支持定时或循环逻辑你可以在界面的 Scripts 选项卡里查看有没有对应能力。实在不行就先用 wscat 这类命令行工具做长时间保活测试Postman 重点做功能验证。4.4 二进制帧与文本帧的处理前面提到过Postman 对二进制帧支持有限。这里的二进制帧指的是 WebSocket 层帧的 opcode 为 0x2数据是原始字节。很多高实时性系统会使用 protobuf、MessagePack 或自定义压缩格式这些内容在 Postman 里就是一堆乱码。遇到这种情况我的操作路径是先在 Postman 里确认连接和消息帧类型确认帧类型是 Binary。然后立刻切换到 Wireshark 抓包看原始字节或者让后端临时加一个 text 格式的调试开关把内容以十六进制或 Base64 的形式输出。记住一点乱码不代表服务端有问题只是 Postman 没帮你解析二进制不要因为界面难看就误判。另外发送二进制消息在 Postman 这边也比较受限Message 输入框主要还是面向文本。如果你需要模拟二进制消息我建议直接用 Node.js 或 Python 写个小脚本把二进制内容发出去Postman 更适合验证协议行为和文本场景。4.5 关闭连接的几种状态码含义WebSocket 断开的时候关闭帧里会带一个状态码。Postman 在连接断开后消息列表或者连接状态区域会展示关闭信息。下面这些码我遇到得最多状态码含义常见触发场景1000正常关闭服务端主动结束业务或客户端正常关闭1001服务端停机后端服务重启、发布上线1002协议错误数据帧格式不对ping/pong 不合规1006异常关闭TCP 直接断开没收到关闭帧网络问题最常见1008政策违规鉴权失败、消息内容不合规1009消息过大超过了服务端允许的帧大小1011服务端内部错误后端处理消息时抛异常排查断连问题时先看这个状态码。如果看到 1006基本说明网络层出了幺蛾子可能是防火墙、NAT 超时、网关把 TCP 连接杀了。如果看到 1008 或 1011再去翻后端日志基本能定位到业务问题。Postman 能帮你快速分类问题这是它最大的价值之一。5. 实战中的常见问题与排查清单5.1 建连失败URL 写错、端口不通、路径被忽略建连失败是最高频的问题原因通常很基础URL 用了http://而不是ws://Postman 直接不接受。端口没写或写错默认 80 或 443 跟实际服务口不一致。路径忽略了。服务端路由可能是/ws你填的是根路径/。连接用了wss://但测试环境证书无效TLS 握手中断了。我有个习惯先用普通 HTTP 请求去探测一下 WebSocket 地址的路径。比如在 Postman 里新建一个 HTTP 请求URL 填http://127.0.0.1:8080/ws如果返回 404说明端口通但路径不对如果连接都连不上说明服务没跑起来或防火墙挡了。这招虽然粗糙但通常能很快缩小问题范围。5.2 连接被服务器主动断开连接成功后马上断开这是第二个高频问题。最常见的原因是鉴权没过、子协议不匹配、心跳超时管理严格、同账号重复连接被踢下线。排查步骤我一般是这样的先看关闭码如果关闭码是 1008优先查鉴权如果关闭码是 1000说明是服务端主动正常关闭那就看业务逻辑里什么时候会触发 close如果关闭码是 1006别只盯业务代码检查网线路由和防火墙策略。还有一个容易忽略的场景测试环境只允许一个连接占同一个账号。你用浏览器登了同一个账号再用 Postman 连后建立的连接可能把前者踢掉或者前身把后者踢掉。这个在调试时经常会让人误判为代码有 BUG实际是连接互斥。5.3 消息收到了但内容不对消息能收到但内容和自己预期不符。我遇到过几种情况文本乱码。字符集问题服务端发的不是 UTF-8而是 GBK 或 ISO-8859-1 编码。Postman 不能改编码得后端统一 UTF-8。JSON 序列化不一致。服务端返回的字段名和文档对不上属于后端 bug 或文档过期用 Postman 看原始 JSON 再对比文档最快。二进制帧。前面讲过看帧类型。多消息顺序错乱。服务端推送频率很高时Postman 消息列表会按到达时间排列你肉眼可能分不清哪条是对应哪条。我建议每条请求消息里带唯一的 messageId服务端回显时带上同样的 id这样在 Postman 里一对应就清楚。5.4 Postman 卡死或内存占用高长时间挂着一个高并发消息流的 WebSocket 连接Postman 的资源占用会涨得很快。因为它要把所有消息都留在界面里供你查看如果每秒几十条推送几十分钟可能积压成千上万条消息界面就开始卡了。我的经验是测试高频数据流时不要一直开着 Postman 的实时消息列表。看一段时间后如果不需要继续观察就断开连接清理一下消息记录再重连。遇到特别高的推送频率我通常改用命令行工具或脚本去拉取Postman 只做低频功能验证。5.5 常见错误对照表现象可能原因排查方法连接状态一直 Connecting网络不通、端口没监听、服务端没启用 WebSocket用 HTTP 请求探测端口和路径握手失败报 Unexpected response code路径写错、网关拦了 Upgrade检查服务端路由确认是否开启 WebSocket 转发连接成功但立刻断开鉴权失败、账号互斥、子协议不对查看关闭码检查 Header 和子协议收到乱码编码问题或二进制帧确认帧类型让后端临时输出文本日志消息发不出去一直超时连接已经断了或服务端不处理消息查看连接状态重新 ConnectPostman 界面卡顿消息量太大断开连接清理消息记录减少消息频率6. 测 WebSocket 的另外几条路6.1 wscat 命令行工具wscat 是 ws 库自带的一个命令行 WebSocket 客户端适合快速连接、发送单条消息、长时间挂机。安装方式特别简单npm install -g wscat然后连上服务wscat -c ws://127.0.0.1:8080进入交互模式后直接输入内容回车就发送。它的优势是轻量、适合脚本化、可以配合 grep 等命令做简单的自动化判断劣势是没法保存多个请求、没有图形界面、没有环境变量管理。我在排查Postman 连不上的问题时经常用 wscat 做对照实验目的就是区分问题是 Postman 配置问题还是服务端问题。6.2 浏览器 DevTools Console浏览器内置的 WebSocket 客户端能力也能用于调试。在 DevTools 的 Console 里执行几行原生 JS就可以建连、发消息、监听事件。const ws new WebSocket(ws://127.0.0.1:8080); ws.onopen () ws.send(hello); ws.onmessage (e) console.log(e.data);这个方式适合验证浏览器环境下的行为但是没法自定义 Header。有些后端鉴权依赖 Cookie浏览器会自动带上而 Postman 里必须要手动管理 Cookie。所以浏览器能连上Postman 连不上这种差异通常就是 Header 或 Cookie 没配齐。6.3 自动化框架与压力工具如果要做自动化回归或性能压力测试Postman 就不是首选了。业界常用的有JMeter 的 WebSocket Sampler 插件可以模拟多用户并发连接做压测和持续集成。Locust 配合 websocket-client 库写 Python 脚本适合更灵活的协议模拟。Node.js 写脚本直接压测能在高并发下统计连接成功率、消息延迟、断线率。这些工具的学习成本都比 Postman 高但在真实线上系统压测、长连接稳定性验证的环节里几乎不可替代。6.4 怎么选我自己的选择逻辑非常直白日常联调和问题复现用 Postman因为能保存、能分享、有环境变量团队协作最省事。快速验证和脚本演示用 wscat轻量直接。压测和 7×24 小时稳定性测试用 JMeter 或 Python/Node 脚本。需要分析底层数据帧和网络丢包时上 Wireshark。每个工具都有明确的适用边界搞清楚边界比纠结哪个工具最强更有意义。在实际工作中最让我头疼的往往不是没有工具而是不知道问题出在哪一层。Postman 最大的价值是帮你在不懂源码的情况下把连接和消息这两个层面拆开来看。连接失败优先看握手的 HTTP 状态和关闭码消息异常优先看帧类型和内容格式这一套思路理清楚WebSocket 接口测试就算入门了。最后再分享一个小技巧保存 WebSocket 请求时把需要的请求头、环境变量和典型消息体都写清楚下次联调或者交接给同事能省大量沟通成本。