Как стать автором
Обновить

Как я писал тестовое задание на Angular и почему некоторым разработчикам не стоит давать тестовое задание

Время на прочтение 7 мин
Количество просмотров 18K

Тестовое задание для junior или middle разработчиков обычно показывает их реальный опыт и понимание предметной области, однако для senior'а тестовое это немного другое. Расскажу свою историю написания маленького тестового задания на Angular с использованием лучших практик.

С чего все началось

У нас в компании обычно жестко распределены роли между разработчиками. Каждый разработчик отвечает за свою часть проекта и ее поддерживает.

Что-то поломалось в 2 часа ночи, отличное время чтобы это исправить. А еще разбудить пару человек, а то что ты один работаешь, а остальные спят.

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

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

Хотя мы все против тестовых заданий, так как считаем их отталкивающей практикой, все-равно иногда появляется разработчик, который 50/50 и непонятно что с ним делать. Чаще всего мы даем тестовое задание, которое можно сделать за 3-6 часов.

У нас простенькое тестовое задание на Angular:

Создать формочку с 3-4 полями, добавить создание объектов и сделать сохранение в localStorage. Опционально добавить карту и вывести объекты на карте.

Цель тестового показать работу c RxJS, Redux, DOM, Работа с формами (Angular Forms) и желательно написать unit тесты, желательно на jest'е.

И однажды делая ревью на тестовое задание кандидата, я написал вот такой фидбек :

Плюсы

  • Проект запускается

  • Проект реализует часть тестового задания

Замечания

  • Не соблюдаются рекомендации оформления (src/app/components/air-routes/air-routes.component.ts:32, src/app/services/data-tickets.service.ts:22)

  • Нет порядка в privite/public свойствах (src/app/components/air-routes/air-routes.component.ts:14)

  • Нет адаптивности в верстке - 480px все поехало

  • Компоненты не используют ChangeDetection

  • Нет lazy loading'а

  • Нет тестов, а автосгенерированные не проходят.

  • Работа с нативным API (localStorage) сделана очень не умело и не обрабатывает кейсы, не говоря про реализацию самой логики.

  • Есть неиспользуемый код, который можно удалить

  • Подключен Angular Router, который не используется

  • При запуске проекта, на главной странице какой-то треш

  • Маршруты строятся не верно. Если ввести A (today) -> B (today + 1) и В (today + 1) -> A (today + 2) - то маршрута A - B - A не будет

  • Нет валидации на даты вылета и прилета - можно выбрать дату прилета из прошлого

  • Нельзя удалить маршрут

  • Нет работы с таймзонами

  • Данные в шаблоне статичны. Можно было хотя бы прелоадеры сделать с текущей даты

Неважные моменты

  • Нет чувства прекрасного, нет вау эффекта

  • Плохо названы переменные (src/app/components/table-ticket/table-ticket.component.html:12, src/app/components/air-routes/air-routes.component.ts:38)

  • Все стили взяты из внешней библиотеки, нет ни строчки кода SCSS

Что почитать:

  • Обновить знания, прочитав документацию по Angular (style-guide, routing, services, testing)

  • Прочитать разделы документации по Typescript, связанные с созданием типов.

  • Обновить знания по JavaScript, и использовать современные конструкции и функции языка

  • Ознокомиться с Redux в Angular (на примере Ngrx, ngsx)

  • Ознакомиться с unit тестированием на примере karma, jest

  • Ознакомиться с современными инструментами разработки Nx

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

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

Разработка тестового задания

Замечу, что у меня "ангулярность". Если вам противен Angular, то перед прочтением посоветуйтесь с вашим ведущим разработчиком, иначе это может вызвать желание миграции на Angular.

И в качестве тестового задания я решил выбрать следующее:

Разработать небольшое приложение, где пользователю показывается карта; на домах расставлены точки (пины). При клике на пин, нужно отобразить информацию о доме. Должен быть функционал добавления пина с соответствующей информацией, а также необходимо реализовать удаления пина. Данные хранить в localStorage.

Еще раз прочитав я подумал, что это можно сделать за пару часов (или дней).

Основные приложения, которые я разрабатываю на основной и любимой работе, используют решение Nx - это реализация монорепозитория для Angular и не только. Однако я еще ни разу не встречал тестовое задание, которое было бы написано с использованием Nx. И поэтому, чтобы не усложнять, я решил использовать стандартные Angular CLI для создания приложения.

Но Nx дал о себе знать, когда я начал создавать приложение. Когда я создавал приложение, Angular еще был 11 версии, а как известно в этой версии еще не было поддержки eslint'а. Пришлось перейти на eslint и добавить prettier.

Затем, увидев karma, я конечно, всплакнул и бесцеремонно удалил karma и настроил тестирование с помощью jest.

Так как Nx предполагает разработку нескольких приложений и набора библиотек, я решил создавать алиасы в TS и использовать их. Это уже не прихоть, а необходимость, так как это позволяет сделать разграничение доступа между модулями("библиотеками").

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

На настройку окружения ушло около часа, осталось еще 3.

Первые звоночки

Начинаем делать проект. И тут я попал в ловушку готовых решений. В данном случае я имею в виду, что разрабатывая тот или иной проект, есть определенный набор решений, который вы используете помимо основного фреймворка. Например, есть сервисы для работы с наборами параметров, которые обрабатывают переменные docker'а, envirionmentService - который унифицирует доступ к environment'ам в Angular и много чего еще. Но в новом проекте этого нет, и что делать с этим не понятно.Я решил перетаскивать по мере необходимости.

Но так делать не стоит. Получилось около 12 core lib, а это явно усложнение тестового задания.

После переноса части библиотек для упрощения работы, я начал с базового - создания шаблона для всего приложения, который включил в себя шапку и подвал, а также определил место вывода основного контента.

Понятно, что свой UI-kit писать не стоит, я взял за основу Angular Material. Но самый главный недостаток Material - нет четкого решения для создания сеток. Видимо разработчики решили, что проще использовать нативный CSS и создавать все через flex, но это же нужно делать.

В итоге, я решил перенести еще одно решение и создать папочку UI, где разместились: сетки, спиннер, карусель и иконки.

Концепт сеток я честно украл у bootstrap и сделал микро реализацию на Angular.

Хотя в Angular есть Angular Flex, который позволяет делать что-то аналогичное, само решение мне не нравиться и взял временами проверенный велосипед.

Создав макет пришло время реализации бизнес логики. Так как Redux наше все, я подключил Ngrx и создал RootState, который является Store.

Перенеся часть утилит из Nx, в частности DataPersistence, я добавил оператор fetch для effect'ов в Ngrx.

Так как весь проект представляет собой часть Airbnb, я создал базовые сущности, создал соответствующие state, сервисы по работе с сущностями, сервисы по работе с нативными хранилищами, фасады и manager'ы, которые подключают в себя разные сущности и отдают гибридные значения.

К этому моменту, наверное уже прошла неделя с момента начала написания тестового задания. Конечно, я писал его только вечерами, где-то по 2-3 часа перед сном, как говорится чтобы лучше спалось. Но верстки еще не было, как и много чего еще.

В этот момент я понял, что написать просто тестовое задание я уже не смогу, но нужно использовать материал по максимуму. Я решил сделать обзорное тестовое задание, в котором бы рассмотрел создания микро приложения от начала до конца, чтобы после прочтения статьи у читателя было понимание, как готовить Angular.

И тогда я открыл habr и начал писать. Однако, когда объем стал слишком большим, я решил, что это будет неправильно и решил разбить статью на несколько маленьких лаконичных статей, где каждая статья бы показывала решение той или иной задачи.

В результате у меня получился цикл из 27 статей посвященных созданию тестового приложения, которые я разместил на своем блоге на Mediume - Тестовое задание на Angular. Введение. Результат можно глянуть на гитхабе: https://github.com/fafnur/barinb.

В результате получилось следующее:

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

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

Где все пошло не так и как к этому относиться

Момент, когда микро приложение стало перерастать в что-то большее, я заметил не сразу. Конечно, основная проблема тут в постановке задачи, так как я больше старался показать разные аспекты, а не выполнить поставленную задачу, в частности быстро написать приложение, которое работало бы.

И тут я задумался о том, а вообще есть смысл в тестовом задании для senior'ов. Мне трудно говорить про свой опыт, так как я думаю я просто высоко оплачиваемый junior, но я решил спросить своих коллег и знакомых на этот счет.

Большинство ребят ответило, что в принципе не делает тестовые задания в РФ. Многие относятся скептически, так как github больше скажет, чем какое-то ненужное задание.

Из тех, кто делал что-то аналогичное, очень часто сталкивались с таким же результатом, что маленькое приложение перерастает в pet проект и так далее.

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

Резюмируя все выше сказанное, можно подвести итог:

  • Вы можете дать тестовое задание senior'у, но шанс, что он его выполнит или выполнит его так, как вы бы этого хотели минимален. Это связано с тем, что разработчик потащит огромный пласт своих "готовых/проверенных" решений, которые в свою очередь могут слишком усложнить проект, который не будет завершен.

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

Если вы все-таки хотите давать тестовые задания, стоит придерживаться следующих правил:

  • Должны быть сроки на выполнение

  • Задание должно быть максимально детализировано, в идеале даже сделать небольшой протитип для UI.

  • Явно обозначить что должно входить в тестовое задание и чего быть не должно.

  • Сделать акценты на те части задания, которые вам кажутся наиболее важными, чтобы разработчик делал действительно то что нужно вам, а не свое авторское видение задачи.

Надеюсь, что это поможет сэкономить время вам и тем разработчикам, которые решат выполнить тестовое задание.

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+17
Комментарии 72
Комментарии Комментарии 72

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн