Анатомия теста в Jasmine

Jasmine — это поведенческая фреймворк для тестирования JavaScript, ориентированная на простоту и читаемость тестов. Основной строительный блок теста — это спецификация (spec). Спецификация описывает поведение функции или модуля и проверяет, соответствует ли оно ожиданиям.

describe: организация тестов

describe используется для группировки связанных тестов. Это функция, которая принимает два аргумента:

  1. Название группы — строка, которая описывает, что тестируется.
  2. Функция с тестами — callback, внутри которого определяются отдельные спецификации.

Пример:

describe('Массивы', function() {
    // Спецификации будут здесь
});

Использование describe позволяет структурировать тесты и делать их читаемыми. Можно вкладывать describe друг в друга для создания иерархии.

it: отдельная спецификация

it описывает одну конкретную проверку поведения. Аргументы:

  1. Описание теста — строка, объясняющая ожидаемое поведение.
  2. Функция с проверкой — callback, содержащий проверки с помощью expect.

Пример:

it('должен добавлять элемент в массив', function() {
    let arr = [];
    arr.push(1);
    expect(arr.length).toBe(1);
});

Каждый it должен быть независимым. Jasmine выполняет их отдельно, обеспечивая изоляцию тестов.

expect и матчер-методы

expect создаёт точку проверки. Она принимает фактическое значение и сравнивается с ожидаемым через матчеры (matchers). Основные виды:

  • toBe(value) — строгая проверка на равенство (===).
  • toEqual(value) — проверка структурного равенства объектов и массивов.
  • toBeTruthy() / toBeFalsy() — проверка на истинность или ложность.
  • toContain(item) — проверка наличия элемента в массиве или строке.
  • toBeDefined() / toBeUndefined() — проверка определения переменной.

Пример:

expect([1, 2, 3]).toContain(2);
expect({a: 1}).toEqual({a: 1});
expect(true).toBeTruthy();

beforeEach и afterEach: подготовка и очистка

beforeEach выполняется перед каждым it в блоке describe. Используется для подготовки окружения или сброса состояния.

describe('Стек', function() {
    let stack;

    beforeEach(function() {
        stack = [];
    });

    it('должен добавлять элементы', function() {
        stack.push(1);
        expect(stack.length).toBe(1);
    });

    it('должен удалять элементы', function() {
        stack.push(1);
        stack.pop();
        expect(stack.length).toBe(0);
    });
});

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

beforeAll и afterAll: глобальная инициализация

beforeAll запускается один раз перед всеми спецификациями блока describe. Это полезно для дорогостоящих операций, которые не нужно повторять перед каждым тестом.

afterAll выполняется один раз после завершения всех тестов блока. Например:

beforeAll(function() {
    console.log('Подготовка данных перед всеми тестами');
});

afterAll(function() {
    console.log('Очистка после всех тестов');
});

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

Jasmine поддерживает асинхронность с помощью done callback или промисов. Если функция теста принимает параметр done, Jasmine ждёт его вызова, прежде чем завершить тест.

it('асинхронный тест с setTimeout', function(done) {
    let value = false;
    setTimeout(function() {
        value = true;
        expect(value).toBe(true);
        done();
    }, 100);
});

Для промисов можно возвращать промис прямо из теста:

it('асинхронный тест с промисом', function() {
    return new Promise(resolve => {
        setTimeout(resolve, 50);
    }).then(() => {
        expect(true).toBe(true);
    });
});

pending тесты

Тест можно отметить как pending, если он ещё не реализован. Для этого достаточно написать xit вместо it или не передавать функцию:

xit('этот тест пока пропущен', function() {
    // Реализация позже
});

it('будет реализован позже');

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

Специфические возможности Jasmine

  • Spies — подменяют функции для проверки вызовов и аргументов.
  • Custom Matchers — возможность создавать собственные матчеры для специфических проверок.
  • Clock — симуляция таймеров и контроля времени в тестах.

Использование этих инструментов позволяет создавать сложные, изолированные, управляемые тестовые сценарии, которые легко поддерживать и расширять.

Итоги структуры теста

Каждый тест в Jasmine строится по схеме: блок describe → отдельные спецификации it → проверки expect → подготовка через beforeEach/afterEach и глобальные хуки beforeAll/afterAll. Асинхронные операции и подмены функций расширяют возможности тестирования. Такой подход обеспечивает модульность, читаемость и надёжность тестов.