Измерение покрытия кода с помощью Jest
Покрытие кода — это метрика, показывающая, какой процент вашего кода выполнился во время работы тестов. Она измеряется по нескольким показателям:
- Statements: сколько операторов
if,return, и т.п. Было выполнено. - Branches: сколько ветвей кода
if-else,switchбыло пройдено. - Functions: сколько функций было вызвано.
- Lines: сколько строк кода было выполнено.
Если все эти цифры не равны 100%, это не значит, что ваш код плохой. Это просто значит, что у вас есть что-то, что вы еще не протестировали. Например, это может быть несущественная часть приложения (но лучше перепроверить!).
Включение покрытия кода в Jest
Jest сам заботится о нас: в нем уже есть встроенная возможность измерения покрытия кода. Чтобы её включить, достаточно добавить флаг --coverage к команде запуска Jest:
npm test -- --coverage
Или обновить ваш package.json для автоматической генерации покрытия:
"scripts": {
"test": "jest --coverage"
}
После запуска вы увидите примерно такой результат в терминале:
-----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------|---------|----------|---------|---------|-------------------
All files | 85.71 | 80.00 | 83.33 | 87.50 |
src | 90.00 | 85.71 | 87.50 | 92.31 |
App.tsx | 100.00 | 100 | 100 | 100 |
MyComponent.tsx | 80.00 | 75.00 | 75.00 | 83.33 | 12, 34, 56
-----------------------|---------|----------|---------|---------|-------------------
Здесь отображена информация о том, какие части кода покрыты тестами, а какие — нет.
Интерпретация отчета покрытия
Читаем результат таблички:
- % Stmts — если покрытие операторов низкое, возможно, вы не тестируете блоки кода внутри
ifилиtry. - % Branch — малое покрытие ветвей говорит о том, что ваши тесты проходят только одну из ветвей, например, только часть
if, но неelse. - % Funcs — низкое покрытие функций может указывать, что вы используете функциональность, которую никто не тестирует. Например, вспомогательные утилиты.
- % Lines — это общее покрытие строк. Важно смотреть, сколько кода не тестируется и почему.
Также обратите внимание на колонку "Uncovered Line #s". Здесь указаны номера строк, которые не попадают под выполнение тестами.
Настройка порогов покрытия
Чтобы убедиться, что все в команде стремятся к единому уровню качества, можно задать минимальные пороги покрытия в конфигурации Jest:
// jest.config.js
module.exports = {
collectCoverage: true,
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};
Теперь, если тесты не достигают заданных порогов, Jest завершится с ошибкой. Это хорошая практика для предотвращения деградации качества.
Улучшение покрытия тестами
Повышение покрытия — не самоцель: важно писать тесты, которые проверяют функциональность, а не просто добавляют зеленые проценты. Вот план действий:
1. Идентификация "непокрытого" кода
Просмотрите отчет покрытия и найдите участки кода, которые не покрыты тестами. Например, если отчет показывает, что строка с номером 34 не покрыта, откройте файл и проверьте:
if (isLoading) {
return <Spinner />;
}
Возможно, вы тестируете состояние, где isLoading равно false, но не проверяете вариант, где оно true.
Добавляем тест для условия isLoading:
test('показывает индикатор загрузки при isLoading = true', () => {
const { getByText } = render(<MyComponent isLoading={true} />);
expect(getByText('Загрузка...')).toBeInTheDocument();
});
2. Покрытие исключительных случаев
Не забывайте про catch или else, которые могут нечасто встречаться, но критически важны. Например, в функции, работающей с API:
try {
const data = await fetchData();
setState(data);
} catch (error) {
console.error(error);
}
Добавьте тесты для случая, когда API падает:
test('обрабатывает ошибки API', async () => {
jest.spyOn(api, 'fetchData').mockRejectedValue(new Error('Ошибка!'));
const { getByText } = render(<MyComponent />);
expect(await getByText('Произошла ошибка')).toBeInTheDocument();
});
Производительность тестов: советы и трюки
Тесты, которые долго выполняются, могут быть проблемой, особенно в больших проектах. Вот как можно ускорить выполнение тестов без потери качества:
Избегайте тестирования всего приложения за раз. Вместо того чтобы прогонять полный набор тестов, запускайте тесты только для измененных файлов:
npm test -- --watchМокайте тяжелую работу. Например, запросы к API можно заменить моками, чтобы избежать реального сетевого взаимодействия:
jest.mock('./api');Параллельный запуск тестов. Jest автоматически запускает тесты параллельно, но вы можете увеличить количество потоков с помощью флага
--maxWorkers.Избегайте дублирования. Если вы видите, что один и тот же код теста повторяется в нескольких местах, вынесите его в общую функцию.
Не забывайте про кеширование. Jest поддерживает кеширование, чтобы не запускать тесты заново для неизмененных файлов. Убедитесь, что кеш включен в настройках:
module.exports = { cacheDirectory: './jestCache', // путь к директории кеша };
Эта лекция показала, что тесты — это не только про "написал и забыл". Работа с покрытием и производительностью тестов помогает поддерживать их актуальность и делает ваш код отзывчивым на изменения. Теперь у вас есть инструменты для этого, так что вперед — тестируйте с удовольствием!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ