Для тестирования кода на Node.js используется Jest — популярный фреймворк, обеспечивающий быстрый запуск тестов, встроенные функции мокирования и удобное покрытие кода. Установка производится через npm:
npm install --save-dev jest
В package.json рекомендуется добавить скрипт для запуска
тестов:
"scripts": {
"test": "jest"
}
После этого можно запускать тесты командой:
npm test
Для проектов с TypeScript часто добавляют ts-jest:
npm install --save-dev ts-jest @types/jest
и создают конфигурационный файл jest.config.js:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
Тесты в Jest группируются в файлы с расширением .test.js
или .spec.js. Основные функции для организации тестов:
describe() — группирует связанные тесты.test() или it() — описывает отдельный
тест.beforeAll(), afterAll(),
beforeEach(), afterEach() — хуки для
подготовки и очистки окружения.Пример структуры:
describe('Математические функции', () => {
let value;
beforeEach(() => {
value = 10;
});
test('Сложение чисел', () => {
expect(value + 5).toBe(15);
});
test('Вычитание чисел', () => {
expect(value - 3).toBe(7);
});
});
Node.js часто работает с асинхронным кодом. Jest поддерживает промисы
и async/await. Для тестирования асинхронных функций можно
использовать:
test('Асинхронная функция возвращает данные', async () => {
const data = await fetchData();
expect(data).toEqual({ success: true });
});
Для функций, возвращающих промис, также работает вариант с
return:
test('Проверка промиса', () => {
return fetchData().then(data => {
expect(data.success).toBe(true);
});
});
Jest позволяет подменять модули и функции для изоляции тестов. Это полезно при тестировании компонентов, которые зависят от базы данных или внешних API.
jest.mock('./api', () => ({
fetchData: jest.fn().mockResolvedValue({ success: true })
}));
test('Тест с мокированной функцией', async () => {
const { fetchData } = require('./api');
const result = await fetchData();
expect(result.success).toBe(true);
});
Для тестирования кода, который выбрасывает ошибки, используются
специальные методы toThrow() и
toThrowError():
function divide(a, b) {
if (b === 0) throw new Error('Деление на ноль');
return a / b;
}
test('Проверка деления на ноль', () => {
expect(() => divide(10, 0)).toThrow('Деление на ноль');
});
Для асинхронных функций, которые выбрасывают ошибки, применяется
rejects:
test('Асинхронная функция выбрасывает ошибку', async () => {
await expect(asyncFunction()).rejects.toThrow('Ошибка выполнения');
});
Jest позволяет генерировать отчёты о покрытии кода с помощью флага
--coverage:
npx jest --coverage
Отчёт содержит информацию о проценте покрытия функций, строк и ветвлений, что помогает выявлять участки кода, требующие дополнительных тестов.
Node.js предоставляет возможность использовать различные окружения
для тестов. В jest.config.js можно настроить:
module.exports = {
testEnvironment: 'node', // или 'jsdom' для браузероподобной среды
verbose: true,
collectCoverage: true
};
Для проверки одного функционала с разными входными данными удобно
использовать test.each():
describe('Проверка сложения чисел', () => {
test.each([
[1, 2, 3],
[5, 5, 10],
[10, -2, 8]
])('Сумма %i и %i равна %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
});
При тестировании функций TensorFlow.js важно учитывать асинхронность операций и освобождение ресурсов. Например:
const tf = require('@tensorflow/tfjs-node');
test('Создание и умножение тензоров', () => {
const a = tf.tensor([1, 2]);
const b = tf.tensor([3, 4]);
const c = a.mul(b);
expect(c.arraySync()).toEqual([3, 8]);
a.dispose();
b.dispose();
c.dispose();
});
Для тестов с моделью можно загружать предварительно сохранённые веса:
test('Прогнозирование модели', async () => {
const model = await tf.loadLayersModel('file://./model/model.json');
const input = tf.tensor2d([[1, 2, 3, 4]]);
const output = model.predict(input);
expect(output.shape).toEqual([1, 1]);
input.dispose();
output.dispose();
});
Для крупных проектов рекомендуется разбивать тесты на отдельные файлы
и папки по функциональным модулям. Jest автоматически находит файлы с
расширениями .test.js и .spec.js. Можно также
создавать конфигурацию roots:
module.exports = {
roots: ['<rootDir>/tests/unit', '<rootDir>/tests/integration'],
};
Это позволяет поддерживать чистую структуру проекта и ускоряет поиск и запуск тестов.