Welcome back to my blog series on using k6 to test the performance of PokeAPI! In this third instalment, I'll discuss different test scenarios, such as load testing, stress testing, and spike testing. I'll also explain how to configure k6 to simulate various user loads and behaviours, and demonstrate how to expand the test script to cover multiple API endpoints. Let's dive in!
Understanding different test scenarios
To thoroughly assess the performance of PokeAPI, it's essential to consider various test scenarios that simulate real-world situations. Here are three common test scenarios:
- Load testing: This scenario measures the API's performance under expected user loads. It helps identify potential bottlenecks and ensure that the API can handle the anticipated traffic.
- Stress testing: This scenario pushes the API to its limits by applying an increasing amount of load until the breaking point is reached. It helps determine the maximum capacity of the API and identify potential points of failure.
- Spike testing: This scenario assesses the API's ability to handle sudden, unexpected increases in user load. It helps ensure that the API can withstand abrupt surges in traffic without experiencing significant performance degradation.
Configuring k6 to simulate different user loads and behaviours
k6 allows me to configure various test settings to accurately simulate different user loads and behaviours. Some key configuration options include:
vus
: This option specifies the number of virtual users (VUs) that will be simulated during the test.duration
: This option sets the test duration (e.g., '30s' for 30 seconds or '10m' for 10 minutes).stages
: This option defines a series of stages with different target VU levels and durations, which is useful for stress and spike testing.
For example, to create a stress test with k6, I can define a series of stages with an increasing number of virtual users:
export let options = {
stages: [
{ duration: '2m', target: 100 }, // ramp up to 100 VUs in 2 minutes
{ duration: '5m', target: 100 }, // maintain 100 VUs for 5 minutes
{ duration: '2m', target: 200 }, // ramp up to 200 VUs in 2 minutes
{ duration: '5m', target: 200 }, // maintain 200 VUs for 5 minutes
{ duration: '2m', target: 0 }, // ramp down to 0 VUs in 2 minutes
],
};
Expanding the test script to cover multiple API endpoints
To create a more comprehensive test script, I can expand it to cover multiple PokeAPI endpoints. For example, I can include tests for the Pokémon list, Pokémon details, and Pokémon abilities endpoints:
import http from 'k6/http';
import { check } from 'k6';
export let options = {
vus: 10, // 10 virtual users
duration: '30s', // test duration
};
export default function () {
const pokemonListResponse = http.get('https://pokeapi.co/api/v2/pokemon');
check(pokemonListResponse, {
'status is 200 for pokemon list': (r) => r.status === 200,
});
const pokemonDetailsResponse = http.get('https://pokeapi.co/api/v2/pokemon/1');
check(pokemonDetailsResponse, {
'status is 200 for pokemon details': (r) => r.status === 200,
});
const abilityListResponse = http.get('https://pokeapi.co/api/v2/ability');
check(abilityListResponse, {
'status is 200 for ability list': (r) => r.status === 200,
});
}
In this updated test script, I've included requests to the Pokémon list, Pokémon details, and Pokémon abilities endpoints. I've also added checks to ensure that the response status code is 200 (OK) for each endpoint.
To run the updated test script, execute the following command in your terminal:
k6 run expanded-pokeapi-test.js
K6 will display real-time information as the test progresses, this includes the number of virtual users, duration, request rates, response times, along with other information. k6 will provide a summary of the test results once the test is complete.
✓ status is 200 for pokemon list
✓ status is 200 for pokemon details
✓ status is 200 for ability list
checks.........................: 100.00% ✓ 8529 ✗ 0
data_received..................: 638 MB 21 MB/s
data_sent......................: 1.1 MB 38 kB/s
http_req_blocked...............: avg=201.33µs min=0s med=1µs max=180.34ms p(90)=1µs p(95)=1µs
http_req_connecting............: avg=21.44µs min=0s med=0s max=25.36ms p(90)=0s p(95)=0s
http_req_duration..............: avg=34.78ms min=10.8ms med=31.09ms max=627.75ms p(90)=55.94ms p(95)=63.15ms
{ expected_response:true }...: avg=34.78ms min=10.8ms med=31.09ms max=627.75ms p(90)=55.94ms p(95)=63.15ms
http_req_failed................: 0.00% ✓ 0 ✗ 8529
http_req_receiving.............: avg=6.27ms min=19µs med=96µs max=139.21ms p(90)=22.19ms p(95)=29.5ms
http_req_sending...............: avg=100.62µs min=20µs med=87µs max=2.57ms p(90)=148µs p(95)=185µs
http_req_tls_handshaking.......: avg=53.73µs min=0s med=0s max=58.88ms p(90)=0s p(95)=0s
http_req_waiting...............: avg=28.4ms min=10.26ms med=25.48ms max=604.5ms p(90)=43.29ms p(95)=49.67ms
http_reqs......................: 8529 283.501386/s
iteration_duration.............: avg=105.69ms min=52.67ms med=101.61ms max=897.87ms p(90)=122.27ms p(95)=131.18ms
iterations.....................: 2843 94.500462/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
To recap, in this blog post, I've discussed various test scenarios, such as load testing, stress testing, and spike testing, and demonstrated how to configure k6 to simulate different user loads and behaviours. I also showed you how to expand the test script to cover multiple API endpoints.
Stay tuned for the next instalment in my blog series, where I'll dive deeper into analysing test results and optimising the performance of PokeAPI based on the insights gained from our tests.