Як створити тестувальник навантаження для API на Node.js
Тестування навантаження — це важлива складова процесу розробки, яка допомагає переконатися, що ваш API витримує високе навантаження та працює стабільно за різних умов. Одним із популярних інструментів для створення кастомних тестувальників є платформа Node.js, яка завдяки своїй асинхронній природі та високій продуктивності чудово підходить для таких завдань.
У цій статті ми розглянемо, як створити власний тестувальник навантаження для API, використовуючи Node.js. Ми створимо скрипт, який зможе надсилати велику кількість запитів до API, аналізувати результати та генерувати звіти про продуктивність.
Основні кроки створення тестувальника
- Вибір інструментів.
- Налаштування середовища Node.js.
- Створення базової структури скрипта.
- Надсилання HTTP-запитів до API.
- Вимірювання продуктивності.
- Генерація звітів.
1. Вибір інструментів
Для реалізації тестувальника ми будемо використовувати наступні бібліотеки:
- Axios: для відправки HTTP-запитів.
- Perf Hooks: для вимірювання часу виконання запитів.
- fs: для збереження результатів у файл.
- dotenv: для роботи зі змінними середовища.
Встановіть їх за допомогою npm:
npm install axios dotenv
2. Налаштування середовища Node.js
Створіть новий проект та налаштуйте середовище:
mkdir load-tester
cd load-tester
npm init -y
Створіть файл .env
для зберігання параметрів API:
API_URL=https://your-api-endpoint.com
REQUESTS=1000
CONCURRENT_USERS=50
3. Створення базової структури скрипта
Створіть файл index.js
та додайте базову структуру:
require('dotenv').config();
const axios = require('axios');
const { performance } = require('perf_hooks');
const API_URL = process.env.API_URL;
const TOTAL_REQUESTS = parseInt(process.env.REQUESTS, 10);
const CONCURRENT_USERS = parseInt(process.env.CONCURRENT_USERS, 10);
let results = [];
const main = async () => {
console.log(`Starting load test with ${TOTAL_REQUESTS} requests and ${CONCURRENT_USERS} concurrent users.`);
// Логіка тестування буде тут
};
main();
4. Надсилання HTTP-запитів до API
Додамо функцію для відправки запитів та обробки відповідей:
const sendRequest = async () => {
const start = performance.now();
try {
const response = await axios.get(API_URL);
const end = performance.now();
return {
success: true,
status: response.status,
time: end - start,
};
} catch (error) {
const end = performance.now();
return {
success: false,
status: error.response ? error.response.status : 'NETWORK_ERROR',
time: end - start,
};
}
};
Додамо функцію для одночасного запуску кількох запитів:
const runLoadTest = async () => {
const promises = Array.from({ length: CONCURRENT_USERS }, async () => {
for (let i = 0; i < TOTAL_REQUESTS / CONCURRENT_USERS; i++) {
const result = await sendRequest();
results.push(result);
}
});
await Promise.all(promises);
};
5. Вимірювання продуктивності
В кінці тесту ми зберемо статистику, яка допоможе оцінити продуктивність API:
const analyzeResults = () => {
const totalRequests = results.length;
const successCount = results.filter((r) => r.success).length;
const failureCount = totalRequests - successCount;
const averageTime = results.reduce((sum, r) => sum + r.time, 0) / totalRequests;
console.log(`\nTest Results:`);
console.log(`Total Requests: ${totalRequests}`);
console.log(`Successful Requests: ${successCount}`);
console.log(`Failed Requests: ${failureCount}`);
console.log(`Average Response Time: ${averageTime.toFixed(2)} ms`);
};
6. Генерація звітів
Додамо функцію для збереження результатів у файл:
const fs = require('fs');
const saveResults = () => {
const report = {
timestamp: new Date().toISOString(),
totalRequests: results.length,
results,
};
fs.writeFileSync('report.json', JSON.stringify(report, null, 2));
console.log('Report saved to report.json');
};
Оновимо функцію main
:
const main = async () => {
console.log(`Starting load test with ${TOTAL_REQUESTS} requests and ${CONCURRENT_USERS} concurrent users.`);
await runLoadTest();
analyzeResults();
saveResults();
};
main();
Повний код скрипта
Ваш файл index.js
має виглядати так:
require('dotenv').config();
const axios = require('axios');
const { performance } = require('perf_hooks');
const fs = require('fs');
const API_URL = process.env.API_URL;
const TOTAL_REQUESTS = parseInt(process.env.REQUESTS, 10);
const CONCURRENT_USERS = parseInt(process.env.CONCURRENT_USERS, 10);
let results = [];
const sendRequest = async () => {
const start = performance.now();
try {
const response = await axios.get(API_URL);
const end = performance.now();
return {
success: true,
status: response.status,
time: end - start,
};
} catch (error) {
const end = performance.now();
return {
success: false,
status: error.response ? error.response.status : 'NETWORK_ERROR',
time: end - start,
};
}
};
const runLoadTest = async () => {
const promises = Array.from({ length: CONCURRENT_USERS }, async () => {
for (let i = 0; i < TOTAL_REQUESTS / CONCURRENT_USERS; i++) {
const result = await sendRequest();
results.push(result);
}
});
await Promise.all(promises);
};
const analyzeResults = () => {
const totalRequests = results.length;
const successCount = results.filter((r) => r.success).length;
const failureCount = totalRequests - successCount;
const averageTime = results.reduce((sum, r) => sum + r.time, 0) / totalRequests;
console.log(`\nTest Results:`);
console.log(`Total Requests: ${totalRequests}`);
console.log(`Successful Requests: ${successCount}`);
console.log(`Failed Requests: ${failureCount}`);
console.log(`Average Response Time: ${averageTime.toFixed(2)} ms`);
};
const saveResults = () => {
const report = {
timestamp: new Date().toISOString(),
totalRequests: results.length,
results,
};
fs.writeFileSync('report.json', JSON.stringify(report, null, 2));
console.log('Report saved to report.json');
};
const main = async () => {
console.log(`Starting load test with ${TOTAL_REQUESTS} requests and ${CONCURRENT_USERS} concurrent users.`);
await runLoadTest();
analyzeResults();
saveResults();
};
main();
Висновок
Створення тестувальника навантаження на Node.js є ефективним підходом для глибокого аналізу продуктивності API. Цей інструмент дозволяє ідентифікувати слабкі місця вашого сервісу, забезпечуючи надійну роботу під час високих навантажень. Розуміння основних принципів роботи та гнучкість Node.js дають можливість створити потужний кастомний інструмент, який буде відповідати вашим потребам.