Мудрые слова от фронт-энда омбудсмена

В прошлом году команда инженеров Ombud работала изо всех сил, чтобы достичь нашей цели - стать ведущей платформой для совместной работы с интеллектуальным контентом. Команда веб-интерфейса (всех нас пятеро!) Была особенно занята внесением улучшений пользовательского интерфейса в наши автоматические предложения, переделыванием нашей модели авторизации и обновлением способа загрузки групп пользователей в нашу систему. В то же время, когда мы приносили пользу организации, мы приняли на работу двух новых разработчиков, вынудили некоторых ключевых разработчиков покинуть организацию и коренным образом изменили то, как мы обеспечиваем качество нашего собственного продукта.

Как и любая небольшая команда в стартапе, мы претерпели множество изменений и смогли продолжить продвигать надежный код и увеличивать нашу скорость. Благодаря новой фиксации на модульном тестировании нашего кода и создании среды, в которой все разработчики вкладываются в развитие привычек. Благодаря хорошему тестированию мы смогли преодолеть все проблемы, которые возникали на нашем пути, и продолжить предоставлять качественный код. В Ombud мы определенно узнали, что модульное тестирование имеет решающее значение для эффективной разработки внешнего интерфейса. В этом сообщении в блоге я расскажу о предпринятых нами шагах, используемых инструментах и ​​процессах, которые мы внедрили для создания культуры модульного тестирования, которая коренным образом изменила то, как мы доставляем программное обеспечение. Если вы разработчик в небольшой команде, которая пытается начать тестирование кода (или унаследовала непроверенную базу кода), и вам необходимо внедрить в своей команде привычки модульного тестирования, эта запись в блоге для вас!

Почему так важны тесты?

Прежде чем мы сможем прояснить способы формирования привычек тестирования в небольшой команде внешнего интерфейса, важно указать причины, по которым тестирование важно и дает ценность при совместной работе над большой кодовой базой. Во-первых, всестороннее тестирование дает нам уверенность в необходимости рефакторинга ранее написанного кода. Хорошо написанный тест правильно определяет минимальное ожидаемое поведение ранее написанной функции или модуля. Это дает индивидуальную уверенность в том, что их модификации или расширения ранее существовавшего кода соответствуют ожиданиям, уже закодированным в системе. Утверждение о том, что разработчик не нарушил существующую функциональность, помогает ограничить количество регрессий, выпускаемых разработчиками. Меньшее количество регрессий создает более счастливых клиентов и более высокий уровень доверия к инженерной группе во всей внутренней организации.

Еще одна важная причина, по которой написание тестов помогает небольшой команде работать быстрее, заключается в том, что тесты сообщают о намерениях продукта на уровне технической реализации. Описания тестов (если они написаны хорошо) содержат ценную информацию об ожидаемом поведении самого продукта. Взгляните на следующие два примера:

Это второе выражение it гораздо более наглядно и поможет разработчику через 3 или 6 месяцев, которому нужно обновить этот код, понять точные намерения написанного кода. Живая запись поможет новому разработчику быстрее (и эффективнее!) Писать код вместо того, чтобы выслеживать человека, который последним прикоснулся к этой части кодовой базы. Получая намерения, лежащие в основе кода, выраженные с помощью модульных тестов, вся команда может расти, учиться и продвигать код быстрее, и команда избегает разрозненности этой информации в пределах одного человека.

Обращение к блокираторам написания тестов

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

  • Выбор простой в освоении утилиты тестирования для простых и удобочитаемых запросов и утверждений в отношении DOM
  • Выявление простых способов имитировать и манипулировать архитектурными компонентами всего приложения, которые многие дочерние компоненты читают из контекста React или функции redux connect, такой как хранилище redux или компонент ThemeProvider Material-UI
  • Имитация структур данных всего приложения - в Ombud многие старые части приложения построены на основе структур данных Immutable.js, поэтому нам нужен был эффективный способ имитировать их с помощью динамических значений для утверждения (если вы создаете свое приложение на TypeScript, вы возможно, ваши интерфейсы уже определены, из которых вы можете легко создавать макеты)

Основываясь на этих критериях, мы использовали следующие инструменты тестирования React:

  • Тестовый раннер / фреймворк - Jest
  • Утилита для тестирования - React Testing Library (мы фактически отказались от использования Enzyme из-за простоты использования API библиотек React Testing Libraries и того, насколько легко / эффективно было проверять вывод HTML-кода компонента React, а не структуру компонент React, который поверхностно обрабатывается Enzyme).
  • Поставщик ложных данных - faker.js

С точки зрения повышения производительности труда разработчиков во время написания тестов. Самый удачный выбор, сделанный командой, - это имитировать наше хранилище redux и MuiThemeProvider из Material-UI в функции рендеринга, которую экспортирует @test-library / response. Это разрешено в любое время, которое мы тестируем с помощью функции рендеринга, например:

И этот компонент (в этом примере EntityMenu) имеет прямую зависимость либо от Redux через функцию подключения, либо от тем Material-UI через контекст, нам не нужно фактически настраивать макеты для внешних библиотек в этом тестовом файле. Мы добились этого, следуя инструкциям на веб-сайте библиотеки тестирования React по настройке пользовательского рендеринга. Этот шаг резко сократил дублирование кода и ненужную сложность многих наших индивидуальных тестов.

Еще один способ упростить разработчикам написание тестов - это потратить время на создание фабрик, которые легко создают имитируемые структуры данных, которые разработчики могут легко использовать (и настраивать) в своих собственных тестах. Например, в платформе Ombud существует концепция EditorItem, которая по сути является связующим звеном между фрагментом структурированного контента и S late.js редактором форматированного текста с открытым исходным кодом, который позволяет пользователю взаимодействовать с этим контентом в браузер. Вот пример фабрики для фиктивного EditorItem:

Мы просто используем параметры по умолчанию JavaScript для создания разумных значений по умолчанию для каждого ключа в EditorItem (который на самом деле является неизменяемой записью). Еще один способ повысить продуктивность разработчиков, когда дело дошло до написания тестов, - это совместная работа над образцами тестов. Мы решили не торопиться и написать несколько более сложных тестов, включая асинхронные потоки данных и более сложные взаимодействия с пользователем (перетаскивание, навигация по страницам, загрузка файлов). Затем мы нашли время, чтобы пообедать и изучить занятия, на которых члены команды делились написанными ими тестами и рассказывали, как они структурировали код для выполнения этих более сложных задач. Самая важная часть этих занятий заключалась в обсуждении того, почему утверждения, которые делают эти тесты, имеют ценность. Эти тесты служат в качестве удобного учебного пособия, на которое разработчики могут ссылаться при написании дополнительных тестов в будущем.

Создание привычных процессов тестирования

Теперь, когда мы уменьшили барьеры на пути к написанию тестов, выбрав наиболее эффективные инструменты, эффективно настроив эти инструменты и создав простые в использовании макеты, следующим шагом была фактическая интеграция тестирования в различные этапы процесса разработки программного обеспечения. Наиболее эффективным шагом, который мы предприняли для внедрения тестирования в процесс разработки, было простое изменение шаблона, который мы используем для проверки PR. Наша команда изменила шаблон вместе на одной встрече после того, как мы договорились, что все будущие PR потребуют прикрепления к ним некоторого типа тестирования. Добавив дополнительные поля, чтобы разработчик мог перечислить типы тестов, которые они написали, и выполнив это вместе, чтобы создать общую команду, мы сделали тестирование более заметным для всех людей, участвующих в процессе проверки PR. Создание этого общего понимания важности тестирования и его интеграция в процесс PR-обзора сыграли решающую роль в формировании новых привычек написания эффективных тестов.

Создание устойчивых привычек к тестированию в небольшой команде разработчиков требует общих обязательств и усилий. Действительно сложно найти баланс между написанием эффективных тестов и тем, чтобы они продолжали приносить пользу вашей компании, организации или проекту. В Ombud мы добились успеха, применив подход, описанный выше. Выбрав правильные инструменты, правильно настроив их для нашей среды, изначально вложив средства в создание повторно используемых ложных данных и интегрировав тестирование как формальную часть нашего PR-процесса, мы смогли написать гораздо больше эффективных тестов за последние 3 месяца. Однако наиболее важно то, что мы создали устойчивую культуру написания тестов. Если вы или ваша команда испытываете трудности с написанием тестов, продолжая приносить пользу своим организациям, я надеюсь, что вы сможете выполнить описанные выше шаги и начать формировать положительные привычки модульного тестирования.