DEV Community

Cover image for How to Use k6 for Comprehensive Testing of Your NestJS API
Agustin Bereciartua
Agustin Bereciartua

Posted on

How to Use k6 for Comprehensive Testing of Your NestJS API

If you've ever worked with NestJS to build an API, you know how important it is to ensure your endpoints are robust and reliable. Enter k6, the open-source tool that's perfect for load testing, stress testing, and more. Let’s explore how you can leverage k6 to put your NestJS API through some rigorous tests. Here’s what you need to know:

Performance Testing with k6

NestJS and k6 make a fantastic pair when you want to ensure your API can handle whatever gets thrown at it. With k6, you can simulate hundreds or thousands of users making simultaneous requests to your API to see how it holds up. This is load testing, and it’s all about simulating expected traffic.

For example:

import http from 'k6/http';
import { sleep } from 'k6';

export let options = {
  vus: 100, // virtual users
  duration: '30s',
};

export default function () {
  http.get('http://localhost:3000/api/users');
  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

This script checks if your NestJS API can handle 100 concurrent users for 30 seconds without breaking a sweat. It's a great starting point for seeing if your infrastructure can handle real-world traffic.

Stress Testing

Unlike load testing, stress testing takes things further. What happens if your API suddenly gets hit by 500, 1000, or even 5000 users? k6 lets you increase the number of virtual users gradually until your API is struggling — allowing you to see exactly where the breaking point is.

export let options = {
  stages: [
    { duration: '1m', target: 100 },  // Ramp up to 100 users
    { duration: '2m', target: 500 },  // Hold at 500 users
    { duration: '1m', target: 0 },    // Ramp down to 0 users
  ],
};
Enter fullscreen mode Exit fullscreen mode

This helps you identify at what point your API begins to slow down or fail, and can also point you to possible bottlenecks in your code or server configuration.

Endurance Testing

Endurance testing (or soak testing) is about testing your NestJS API over a long period. You want to know if your API can maintain its performance and stability over hours or even days of constant requests. With k6, this is as easy as adjusting the duration in your test script.

export let options = {
  vus: 50,
  duration: '4h', // Testing the API stability for 4 hours
};
Enter fullscreen mode Exit fullscreen mode

This kind of test will help you identify memory leaks and other long-term stability issues in your application.

API Functional Testing

k6 can also help with functional testing by checking if your endpoints return the correct data and status codes. Here’s a quick example:

import http from 'k6/http';
import { check } from 'k6';

export default function () {
  let response = http.get('http://localhost:3000/api/users/1');
  check(response, {
    'status is 200': (r) => r.status === 200,
    'user data is correct': (r) => r.json().name === 'John Doe',
  });
}
Enter fullscreen mode Exit fullscreen mode

This ensures that your API returns the expected status code and data. Simple, but essential for catching bugs early on.

Spike Testing

What happens if your app gets sudden bursts of traffic? That’s where spike testing comes in. With k6, you can create short, intense bursts of virtual users to see how well your NestJS API handles unexpected traffic spikes.

export let options = {
  stages: [
    { duration: '10s', target: 500 }, // Spike to 500 users
    { duration: '20s', target: 0 },   // Drop to 0 users
  ],
};
Enter fullscreen mode Exit fullscreen mode

If your NestJS API can gracefully handle this sudden surge and return to normal without issues, you're in a good place.

Ramp-Up and Ramp-Down Tests

A good practice is to gradually ramp up the number of users and then ramp down, which can help simulate real-world scenarios where traffic increases and decreases over time.

export let options = {
  stages: [
    { duration: '1m', target: 50 },   // Slowly ramp up to 50 users
    { duration: '3m', target: 200 },  // Ramp up more significantly to 200 users
    { duration: '1m', target: 0 },    // Gradually bring back to 0
  ],
};
Enter fullscreen mode Exit fullscreen mode

This helps you determine if your API can handle gradual changes in load, without surprising failures.

Example TypeScript k6 Script

To make your scripts more manageable, you can write them in TypeScript. Here’s an example of how you can write a simple load test using TypeScript and k6:

  1. Install k6 TypeScript support using npm:
npm install --save-dev typescript k6
Enter fullscreen mode Exit fullscreen mode
  1. Create a TypeScript script, for example, loadTest.ts:
import http from 'k6/http';
import { sleep, check } from 'k6';
import { Options } from 'k6/options';

export const options: Options = {
  vus: 10, // virtual users
  duration: '5m', // duration of the test
};

export default function () {
  const res = http.get('http://localhost:3000/book');
  check(res, {
    'status was 200': (r) => r.status === 200,
    'duration was <= 200ms': (r) => r.timings.duration <= 200,
  });
  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode
  1. Compile the TypeScript script to JavaScript:
ts-node loadTest.ts
Enter fullscreen mode Exit fullscreen mode

This allows you to leverage TypeScript’s type-checking capabilities, making your tests more maintainable and less prone to errors.

Why Use k6 with NestJS?

The simplicity of k6 combined with the structured nature of NestJS makes testing an absolute breeze. By leveraging the various forms of testing available — load, stress, endurance, functional, spike, and more — you can ensure that your API is production-ready, robust, and capable of handling whatever traffic comes your way.

Want to make sure your NestJS API is unstoppable? Give k6 a try and explore its full potential for a smoother, worry-free production release!

Top comments (0)