Юнит-тесты для кода на Bliss

Bliss.js предоставляет мощный и гибкий инструмент для организации юнит-тестов, позволяя создавать тестовые сценарии для различных компонентов JavaScript-приложений. Юнит-тестирование фокусируется на проверке отдельных функций, методов и модулей на корректность их работы в изоляции от остальной системы.

В Bliss.js тесты создаются через встроенные функции test и suite, которые обеспечивают структурированное выполнение проверок и отчетность о результатах.

import { suite, test, assert } from 'blissjs';

suite('Математические функции', () => {
    test('Сложение двух чисел', () => {
        const result = add(2, 3);
        assert.equal(result, 5, '2 + 3 должно быть равно 5');
    });

    test('Вычитание чисел', () => {
        const result = subtract(10, 4);
        assert.equal(result, 6, '10 - 4 должно быть равно 6');
    });
});

В примере показано создание набора тестов (suite) и двух тест-кейсов (test). Основные элементы:

  • suite(name, callback) — определяет группу тестов с читаемым именем.
  • test(name, callback) — отдельный тестовый кейс, проверяющий конкретную функциональность.
  • assert — объект с методами для проверки значений, аналогичный популярным библиотекам типа Chai.

Ассерты и проверки

Bliss.js поддерживает несколько видов проверок:

  • assert.equal(actual, expected, message) — проверка строгого равенства.
  • assert.notEqual(actual, expected, message) — проверка на неравенство.
  • assert.ok(value, message) — проверка на истинность выражения.
  • assert.throws(fn, expectedError, message) — проверка на генерацию ошибки при выполнении функции.

Пример проверки ошибки:

test('Деление на ноль вызывает ошибку', () => {
    assert.throws(() => divide(5, 0), Error, 'Должна быть выброшена ошибка при делении на ноль');
});

Такой подход обеспечивает точное выявление неправильного поведения функций и позволяет отслеживать изменения в логике приложения.


Асинхронные тесты

Bliss.js полностью поддерживает асинхронные операции через async/await. Тест-кейсы могут возвращать промисы или использовать асинхронные функции:

test('Асинхронное получение данных', async () => {
    const data = await fetchData();
    assert.ok(Array.isArray(data), 'Данные должны быть массивом');
    assert.equal(data.length, 5, 'Длина массива должна быть 5');
});

Асинхронные тесты особенно важны при работе с API, базами данных или таймерами.


Подготовка и очистка данных

Для сложных сценариев Bliss.js предоставляет хуки:

  • before(callback) — выполняется один раз перед всеми тестами в сьюте.
  • after(callback) — выполняется один раз после всех тестов.
  • beforeEach(callback) — выполняется перед каждым тестом.
  • afterEach(callback) — выполняется после каждого теста.

Пример:

suite('Работа с пользователями', () => {
    let user;

    before(() => {
        console.log('Запуск перед всеми тестами');
    });

    beforeEach(() => {
        user = createUser('test', 'password');
    });

    afterEach(() => {
        deleteUser(user.id);
    });

    test('Создание пользователя', () => {
        assert.ok(user.id, 'У пользователя должен быть id');
    });

    test('Проверка имени пользователя', () => {
        assert.equal(user.name, 'test', 'Имя должно совпадать с ожидаемым');
    });
});

Хуки позволяют изолировать тестовые данные, избегая побочных эффектов между тестами.


Параметризованные тесты

Bliss.js поддерживает создание тестов с разными входными данными через массивы и циклы, что сокращает дублирование кода:

const cases = [
    { a: 1, b: 2, expected: 3 },
    { a: -1, b: -2, expected: -3 },
    { a: 0, b: 0, expected: 0 },
];

cases.forEach(({ a, b, expected }) => {
    test(`Сложение ${a} + ${b} = ${expected}`, () => {
        assert.equal(add(a, b), expected);
    });
});

Такой подход особенно удобен для математических и логических функций, где требуется проверить множество комбинаций.


Моки и заглушки

Bliss.js предоставляет встроенные возможности для создания моков функций и объектов, что позволяет изолировать тестируемую логику от внешних зависимостей:

test('Использование мока для API', () => {
    const apiMock = {
        fetchUser: () => ({ id: 1, name: 'Mock User' })
    };
    
    const user = getUser(apiMock);
    assert.equal(user.name, 'Mock User');
});

Моки помогают тестировать функции без необходимости реального вызова API или работы с базой данных.


Запуск и отчётность

Тесты в Bliss.js можно запускать через CLI или интеграцию с Node.js:

bliss run tests/

Библиотека автоматически собирает статистику по пройденным и проваленным тестам, выводит подробные сообщения об ошибках и стек-трейсы, позволяя быстро локализовать проблему.


Организация крупных тестовых наборов

Для крупных проектов рекомендуется:

  • Разделять тесты по модулям и функциональным блокам.
  • Использовать отдельные сьюты для разных типов тестов (синхронные, асинхронные, интеграционные).
  • Применять хуки для повторяющихся операций.
  • Писать читаемые и самодокументируемые тест-кейсы с понятными сообщениями в assert.

Рекомендации по стилю

  • Каждый тест должен проверять одну конкретную функциональность.
  • Избегать длинных тестов с множеством проверок — лучше разделить на несколько кейсов.
  • Использовать информативные названия сьютов и тестов.
  • Минимизировать внешние зависимости и побочные эффекты для надежной повторяемости.

Юнит-тесты в Bliss.js обеспечивают стабильность кода, ускоряют отладку и делают проект легко сопровождаемым даже при больших объёмах кода.