k6

A modern load testing tool, using Go and JavaScript

"like unit testing, for performance"

k6 is a modern load testing tool, building on Load Impact's years of experience. It provides a clean, approachable JavaScript scripting API, distributed and cloud execution, and orchestration via a REST API.

Get Started    Guides

k6/ws

k6 WebSocket API

The ws module provides a WebSocket client implementing the WebSocket protocol.

Methods
Description

Create a WebSocket connection, and provides a Socket client to interact with the service. The method returns a Response (k6/http) object and blocks the test finalization until the connection is closed.

Socket client methods
Description

Set up an event listener on the connection for any of the following events:

  • open
  • message
  • ping
  • pong
  • close
  • error

Send data.

Send a ping.

Call a function with a delay, if the connection is open.

Call a function repeatedly at certain intervals, while the connection is open.

Close WebSocket connection.

WebSocket built-in metrics

k6 will automatically collect some metrics when interacting with a WebSocket service through the k6/ws API.

Metric name
Type
Description

ws_connecting

Trend

Total duration for the WebSocket connection request.

ws_session_duration

Trend

Duration of the WebSocket session. Time between the start of the connection and the end of the VU execution.

ws_sessions

Counter

Total number of started WebSocket sessions.

ws_ping

Trend

Duration between a ping request and its pong reception.

ws_msgs_sent

Counter

Total number of messages sent through Socket.send(data)

ws_msgs_received

Counter

Total number of received messages Socket.on('message', callback)

Check out the Results output article for more information about how to process the metric information.

import ws from "k6/ws";
import { check } from "k6";

export default function() {
  var url = "ws://echo.websocket.org";
  var params = { "tags": { "my_tag": "hello" } };
  
  var response = ws.connect(url, params, function (socket) {
    socket.on('open', function open() {
      console.log('connected');
      socket.send(Date.now());

      socket.setInterval(function timeout() {
        socket.ping();
        console.log("Pinging every 1sec (setInterval test)");
      }, 1000);
    });

    socket.on('ping', function () {
      console.log("PING!");
    });

    socket.on('pong', function () {
      console.log("PONG!");
    });

    socket.on('pong', function () {
      // Multiple event handlers on the same event
      console.log("OTHER PONG!");
    });

    socket.on('message', function (message) {
      console.log(`Received message: ${message}`);
    });

    socket.on('close', function () {
      console.log('disconnected');
    });

    socket.on('error', function (e) {
      if (e.error() != "websocket: close sent") {
        console.log('An unexpected error occured: ', e.error());
      }
    });

    socket.setTimeout(function () {
      console.log('2 seconds passed, closing the socket');
      socket.close();
    }, 2000);
  });

  check(response, { "status is 101": (r) => r && r.status === 101 });
}
//VU execution won't be completely finished until the connection is closed.