В процессе разработки на JavaScript тесты занимают ключевое место. Одним из важнейших аспектов тестирования является правильное именование тестов, поскольку оно влияет не только на читаемость кода, но и на его поддержку в будущем. Jest, как популярная библиотека для тестирования, предлагает определённые стандарты и подходы к именованию тестов, которые способствуют улучшению понимания логики тестов и быстрому нахождению ошибок.
Ясность и конкретность — имена тестов должны чётко
отражать, что именно тестируется, и какой результат ожидается. Если тест
не может быть прочитан и понят без подробных комментариев, это
свидетельствует о проблемах в структуре самого теста. Вместо того, чтобы
использовать общие фразы типа test('works correctly'),
лучше указать точное поведение функции или компонента, которое
проверяется.
Использование глаголов в настоящем времени — так как тесты обычно описывают действия, важно использовать глаголы в настоящем времени. Это поможет формулировать тесты как утверждения о текущем поведении кода. Пример:
test('должен возвращать правильный результат при передаче отрицательных чисел', () => {
expect(add(-1, -2)).toBe(-3);
});
Jest предоставляет несколько вариантов синтаксиса для описания
тестов. Наиболее распространённые функции — это test и
it. В отличие от test, который используется с
ключевым словом, как в примере выше, it предоставляет более
читабельную структуру, особенно при использовании в описаниях:
it('должен возвращать правильный результат при передаче отрицательных чисел', () => {
expect(add(-1, -2)).toBe(-3);
});
Этот синтаксис не влияет на поведение теста, но может улучшить восприятие, особенно когда тесты описывают поведение функции с точки зрения пользователя.
Имена тестов должны описывать поведение системы, а не её внутреннюю реализацию. Это позволяет тестам оставаться актуальными даже в случае изменений в коде, не влияющих на конечный результат. Например, тест, проверяющий правильность вычисления суммы двух чисел, не должен зависеть от того, как именно эта сумма рассчитывается.
Пример:
// Плохо
test('должен вызывать функцию calculateSum и возвращать результат', () => {
// внутренности теста, проверяющие вызов конкретной функции
});
// Хорошо
test('должен правильно суммировать два числа', () => {
expect(add(2, 3)).toBe(5);
});
В последнем примере описано именно поведение системы, и тест остаётся
актуальным даже если в будущем изменится способ реализации функции
add.
Для логичной структуры тестов рекомендуется использовать блоки
describe, которые позволяют группировать тесты по
функциональности. Каждый блок describe может быть
использован для группировки тестов, относящихся к определённому аспекту
программы. Внутри таких блоков можно использовать более специфичные
имена для каждого теста.
Пример:
describe('Функция add', () => {
test('должна правильно суммировать положительные числа', () => {
expect(add(2, 3)).toBe(5);
});
test('должна правильно суммировать отрицательные числа', () => {
expect(add(-2, -3)).toBe(-5);
});
test('должна возвращать правильный результат при смешанных знаках', () => {
expect(add(-2, 3)).toBe(1);
});
});
Использование describe позволяет обеспечить лёгкую
навигацию по тестам и упрощает их восприятие, особенно при большом
количестве проверок.
test('должен возвращать правильную сумму двух чисел', () => {
expect(sum(1, 2)).toBe(3);
});
test('должен корректно обрабатывать асинхронные запросы', async () => {
const data = await fetchData();
expect(data).toBeDefined();
});
describe('Компонент Button', () => {
test('должен рендерить текст по умолчанию', () => {
const { getByText } = render(<Button />);
expect(getByText('Нажми меня')).toBeInTheDocument();
});
test('должен вызывать функцию при клике', () => {
const handleClick = jest.fn();
const { getByText } = render(<Button onCl ick={handleClick} />);
fireEvent.click(getByText('Нажми меня'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
test('должен выбрасывать ошибку, если аргумент не является числом', () => {
expect(() => {
add('a', 3);
}).toThrow('Аргументы должны быть числами');
});
Использование шаблонов и фраз — создание единых шаблонов для именования тестов позволяет повысить их предсказуемость. Например, все тесты, проверяющие функцию, могут начинаться с одинакового слова, например: “должен правильно…”, “должен возвращать…”, “должен выбрасывать ошибку…”.
Минимизация избыточности — избегание избыточных описаний может значительно упростить восприятие тестов. Например, вместо того чтобы писать “должен вернуть результат, который равен 5”, можно просто написать “должен вернуть 5”.
Использование параметризированных тестов — для
проверки одинакового поведения с разными входными данными полезно
использовать параметризированные тесты. Jest поддерживает это через
функцию each.
describe('Функция add', () => {
test.each([
[1, 2, 3],
[-1, -2, -3],
[2, -3, -1],
])('должна правильно суммировать %i и %i', (a, b, expected) => {
expect(add(a, b)).toBe(expected);
});
});
В рамках крупной команды или проекта полезно установить чёткие стандарты для именования тестов. Это позволяет избежать путаницы и несоответствий в стиле имен. Стандарты могут включать:
describe и
вложенных тестов.Такие стандарты делают тесты более читабельными и удобными для поиска, что ускоряет процесс разработки и улучшает качество кода.