Тестовое задание: мысли, подход и реализация
Задача и мои мысли
Недавно я проходил собеседование в одной компании, и мне прислали небольшое тестовое задание. У меня как раз был свободный день, и я решил подойти к нему серьёзно – так, как если бы это была реальная рабочая задача.
О задании
Задание представляло собой работу с приложением для управления задачами (Task Manager), написанным на React, TypeScript и Tailwind CSS. Основные требования включали:
-
Исправление багов:
- Фильтр задач работал некорректно.
- Удаление задачи не сразу обновляло интерфейс.
- Были проблемы с консистентностью стилей и TypeScript-ошибками.
-
Улучшение кода: Рефакторинг для повышения читаемости и поддерживаемости.
-
Дополнительные улучшения: Возможность добавить сохранение задач в локальное хранилище, улучшение UI/UX, настройка CI/CD и написание тестов.
Подробное описание задания можно найти в этом репозитории.
Сам проект очень простой: форма для добавления задач, таблица со списком и фильтрацией, кнопка удаления. В таких задачах скорее оценивается стиль работы, оформление PR, коммитов и организация кода, а не сложность самой реализации.
В реальной работе код проходит ревью другими членами команды, и важно оформлять его так, чтобы на это уходило минимальное время. Также важна история изменений со ссылками на задачи, чтобы всегда можно было понять, почему и кем было сделано то или иное изменение.
План решения
Я решил выполнять задание в несколько этапов, разбив изменения на логические блоки. Каждый этап оформил в отдельный PR, чтобы их можно было удобно ревьюить.
Для порядка и хорошего тона завел задачу на каждый этап в GitHub Issues
1. Наведение порядка в проекте
Сначала я добавил линтеры, настроил TypeScript и ESLint. Это базовые вещи, которые сразу приводят код в порядок, предотвращают ошибки и упрощают дальнейшую работу.
PR: Настройка линтеров и TypeScript
2. Настройка деплоя и CI/CD
Следующим этапом я решил настроить автоматическую проверку сборки при каждом PR и деплой в GitHub Pages из ветки main. Это полезно как для тестирования изменений, так и для удобного просмотра результатов.
3. Исправление багов
Заданные баги были несложными. Судя по коду и комментариям, они были оставлены специально (что логично для тестового задания). В фильтре были перепутаны стили, функции работали немного некорректно.
Я исправил:
- Неправильную работу фильтра.
- Обновление UI после удаления задачи (раньше оно происходило с задержкой).
- Инконсистентность стилей Tailwind CSS.
- Ошибки TypeScript и отсутствующие типы.
Я не буду сильно подробно останаливаться тут, мне кажется что изменения в коде понятнее чем описание словами.
4. Добавление постоянного хранения задач
Я решил использовать IndexedDB вместо LocalStorage, так как это более подходящее решение:
- IndexedDB асинхронен, не блокирует основной поток.
- Нет ограничений на размер хранилища.
- Лучше подходит для работы с большими объемами данных.
На мой взгляд, IndexedDB незаслуженно редко используется в фронтенд-разработке. В 2025 году мы всё ещё храним данные в store и загружаем их из API при каждом запросе, хотя в браузере есть встроенное хранилище, которое можно эффективно использовать.
5. Написание тестов
Обычно я предпочитаю интеграционные и e2e-тесты, а не покрытие каждого компонента unit-тестами. Отдельное тестирование компонентов часто сводится к проверке наличия классов и кликов по кнопкам, что мало связано с реальной бизнес-логикой. Такие тесты создают накладные расходы на поддержку, но не дают особой пользы.
Гораздо важнее покрывать тестами сервисы и сложную логику. В данном случае я написал:
- Unit-тесты для компонентов (чтобы показать, что умею их писать – всё-таки это тестовое задание).
- Интеграционный тест для сервиса, который работает с IndexedDB. Пришлось добавить библиотеки для эмуляции IndexedDB API в тестах.
Заключение
В итоге я решил задачу так, как если бы работал над реальным проектом: структурировал изменения, оформил цепочку PR для удобного ревью, исправил баги, добавил IndexedDB и тесты. Такой подход помогает не только быстрее разбираться в коде, но и делает процесс разработки более прозрачным.
Если интересно, можете посмотреть репозиторий с открытыми PR.