WebSocket Testing Tools: Complete Guide (2025)
The best tools for testing WebSocket connections. Covers browser-based testers, CLI tools, load testing, debugging techniques, and common WebSocket issues.
WebSockets enable real-time bidirectional communication β chat apps, live dashboards, collaborative editing, and push notifications all depend on them. But unlike REST APIs, WebSockets maintain persistent connections, which makes testing them fundamentally different.
This guide covers every tool and technique you need to test WebSocket connections, from browser DevTools to CLI clients to load testing.
Understanding the WebSocket Lifecycle
Before testing, understand what youβre testing:
Client Server
| |
|---HTTP GET (Upgrade request)->|
|<--101 Switching Protocols-----|
| |
|====WebSocket Connection=======|
| |
|---{ "type": "ping" }--------->|
|<--{ "type": "pong" }----------|
| |
|---Connection Close----------->|
|<--Connection Close------------|
The WebSocket connection starts as an HTTP request with an Upgrade: websocket header. If the server accepts, it responds with 101 Switching Protocols and the WebSocket session begins.
What youβll test:
- Connection establishment: Can you connect?
- Message sending/receiving: Are messages delivered correctly?
- Message format: JSON, binary, text?
- Reconnection: Does the client reconnect on disconnect?
- Error handling: What happens when the server sends an error?
- Load: How many concurrent connections can the server handle?
1. Browser DevTools (Built-in)
Best for: Inspecting existing WebSocket connections in web apps
Chrome, Firefox, and Edge all support WebSocket inspection in the Network tab:
- Open DevTools β Network tab
- Filter by WS (WebSocket)
- Reload the page or trigger the WebSocket connection
- Click the WebSocket connection in the list
- Go to the Messages tab to see all frames
What you can see:
- Initial HTTP Upgrade request and headers
- All sent and received messages with timestamps
- Message sizes
- Binary vs text frames
Limitation: DevTools only shows connections initiated by the current page. You canβt initiate new connections from here.
2. Browser Console
Best for: Quick ad-hoc WebSocket testing without any tools
Open any browser console and test a WebSocket directly:
// Connect to a WebSocket server
const ws = new WebSocket('wss://echo.websocket.events');
// Set up event handlers
ws.onopen = () => {
console.log('Connected');
ws.send('Hello, WebSocket!');
};
ws.onmessage = (event) => {
console.log('Received:', event.data);
};
ws.onerror = (error) => {
console.error('Error:', error);
};
ws.onclose = (event) => {
console.log('Disconnected:', event.code, event.reason);
};
Sending JSON messages:
ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
Sending messages at intervals:
const interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping', timestamp: Date.now() }));
} else {
clearInterval(interval);
}
}, 1000);
Closing the connection:
ws.close(1000, 'Normal closure');
3. websocat (CLI)
Best for: Terminal-based WebSocket testing and scripting
websocat is the WebSocket equivalent of netcat β a powerful CLI client.
Install:
# macOS
brew install websocat
# Linux (download binary)
wget https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl
chmod +x websocat.x86_64-unknown-linux-musl
sudo mv websocat.x86_64-unknown-linux-musl /usr/local/bin/websocat
Basic usage:
# Connect and interact interactively
websocat wss://echo.websocket.events
# Type messages, see responses
Pipe messages:
# Send a single message and exit
echo "Hello" | websocat wss://echo.websocket.events
# Send JSON
echo '{"type":"ping"}' | websocat wss://your-server.com/ws
With authentication headers:
websocat -H "Authorization: Bearer YOUR_TOKEN" wss://api.example.com/ws
Continuous message stream:
# Send a new message every second
while true; do
echo '{"type":"heartbeat","ts":'$(date +%s)'}'
sleep 1
done | websocat wss://api.example.com/ws
Listen for N messages then exit:
websocat --no-close -n 5 wss://api.example.com/ws
4. Postman
Best for: Teams already using Postman for REST API testing
Postman added WebSocket support in 2021. It provides a GUI for WebSocket testing alongside your existing REST collections.
To use:
- Click New β WebSocket Request
- Enter the WebSocket URL
- Add headers if needed (under the Headers tab)
- Click Connect
- Type messages in the Message input and press Send
Postman WebSocket features:
- Save connections and messages to collections
- Add authentication headers
- Support for JSON and text messages
- Message history per session
Limitation: WebSocket collections canβt be automated in the same way as REST collections.
5. Insomnia
Best for: Developers using Insomnia for API testing
Insomnia supports WebSocket connections alongside REST and GraphQL:
- Create a new WebSocket request
- Set the URL, headers, and connection settings
- Connect and send messages interactively
Insomnia supports environment variables in WebSocket URLs, making it easy to switch between dev/staging/production.
6. wscat (Node.js CLI)
Best for: Node.js developers who want a familiar tool
# Install globally
npm install -g wscat
# Connect
wscat -c wss://echo.websocket.events
# With headers
wscat -c wss://api.example.com/ws \
-H "Authorization: Bearer TOKEN"
# With subprotocols
wscat -c wss://api.example.com/ws \
--subprotocol "chat,notifications"
7. Testing WebSockets in Node.js Scripts
Best for: Automated tests and CI pipelines
Use the ws library for programmatic WebSocket testing:
const WebSocket = require('ws');
async function testWebSocket(url) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(url);
const messages = [];
const timeout = setTimeout(() => {
ws.close();
reject(new Error('WebSocket timeout'));
}, 5000);
ws.on('open', () => {
console.log('Connected to', url);
ws.send(JSON.stringify({ type: 'ping' }));
});
ws.on('message', (data) => {
const msg = JSON.parse(data.toString());
messages.push(msg);
if (msg.type === 'pong') {
clearTimeout(timeout);
ws.close();
resolve(messages);
}
});
ws.on('error', reject);
});
}
// Run the test
testWebSocket('wss://your-server.com/ws')
.then(messages => console.log('Test passed:', messages))
.catch(err => console.error('Test failed:', err));
Jest integration:
describe('WebSocket server', () => {
let ws;
beforeEach((done) => {
ws = new WebSocket('ws://localhost:3001');
ws.on('open', done);
});
afterEach(() => {
ws.close();
});
test('responds to ping with pong', (done) => {
ws.send(JSON.stringify({ type: 'ping' }));
ws.on('message', (data) => {
const msg = JSON.parse(data);
expect(msg.type).toBe('pong');
done();
});
});
test('broadcasts messages to all clients', (done) => {
const ws2 = new WebSocket('ws://localhost:3001');
ws2.on('open', () => {
ws.send(JSON.stringify({ type: 'broadcast', text: 'hello' }));
});
ws2.on('message', (data) => {
const msg = JSON.parse(data);
expect(msg.text).toBe('hello');
ws2.close();
done();
});
});
});
Load Testing WebSockets
Using Artillery
# artillery-ws.yml
config:
target: "wss://your-server.com"
phases:
- duration: 60
arrivalRate: 10 # 10 new connections per second
scenarios:
- engine: "ws"
flow:
- connect: "/ws"
- send: '{"type": "subscribe", "channel": "updates"}'
- think: 5
- send: '{"type": "ping"}'
- think: 10
npm install -g artillery
artillery run artillery-ws.yml
Using k6
// k6-ws-test.js
import ws from 'k6/ws';
import { check } from 'k6';
export const options = {
vus: 100, // 100 virtual users
duration: '30s',
};
export default function () {
const url = 'wss://your-server.com/ws';
const response = ws.connect(url, {}, function (socket) {
socket.on('open', () => {
socket.send(JSON.stringify({ type: 'subscribe' }));
});
socket.on('message', (data) => {
const msg = JSON.parse(data);
check(msg, { 'message received': (m) => m.type !== undefined });
});
socket.setTimeout(() => socket.close(), 5000);
});
check(response, { 'status is 101': (r) => r && r.status === 101 });
}
Common WebSocket Issues and Fixes
Connection Fails with 403
The server is rejecting the handshake. Common causes:
- Missing or incorrect
Originheader - Authentication required
- CORS misconfiguration
# Check what the server expects
websocat -v wss://api.example.com/ws 2>&1 | head -30
Messages Drop Under Load
Implement a message queue and acknowledgment system:
const pendingAcks = new Map();
function sendWithAck(ws, message) {
const id = Date.now();
const payload = { ...message, id };
pendingAcks.set(id, payload);
ws.send(JSON.stringify(payload));
setTimeout(() => {
if (pendingAcks.has(id)) {
console.warn('Message not acknowledged, resending:', id);
ws.send(JSON.stringify(payload));
}
}, 3000);
}
Connection Dies After 30-60 Seconds
Load balancers and proxies close idle connections. Implement heartbeat:
const heartbeat = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
}
}, 25000); // Every 25 seconds
ECONNREFUSED in Tests
Your WebSocket server isnβt starting before the tests run. Add a wait:
function waitForWebSocket(url, timeout = 5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
function attempt() {
const ws = new WebSocket(url);
ws.on('open', () => { ws.close(); resolve(); });
ws.on('error', () => {
if (Date.now() - start > timeout) reject(new Error('Timeout'));
else setTimeout(attempt, 100);
});
}
attempt();
});
}
Quick Testing Checklist
- Can you establish a connection?
- Does the server send a welcome/connected message?
- Can you send a message and receive a response?
- Does the server handle malformed JSON gracefully?
- Does the server close the connection cleanly?
- Does your client reconnect after a disconnect?
- Does the connection survive a 30-second idle period (heartbeat working)?
- Under load, are messages delivered without dropping?
Related Tools
- DevPlaybook API Tester β Test REST APIs alongside WebSocket services
- DevPlaybook CORS Tester β Debug CORS issues affecting WebSocket upgrades
- DevPlaybook API Request Builder β Build authentication flows before connecting
Level Up Your Real-Time Stack
Building a production WebSocket service? The Full-Stack Boilerplate Collection includes a Node.js API starter with WebSocket support, Redis pub/sub integration, and reconnection handling already built in.
Free Newsletter
Level Up Your Dev Workflow
Get new tools, guides, and productivity tips delivered to your inbox.
Plus: grab the free Developer Productivity Checklist when you subscribe.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links β we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.