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

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

Если вы хотите глубже погрузиться в тему, я создал БЕСПЛАТНЫЙ онлайн-курс, который охватывает все темы, обсуждаемые в этом посте, и многое другое. Этот курс разработан, чтобы быть интерактивным, увлекательным и наполнен практическими советами и методами. К концу курса вы будете иметь четкое представление о предмете и сможете применять полученные знания в повседневной жизни.

1. Постановка задач

Мы будем использовать Buy Some Milk в качестве примера в этой статье, если вы хотите узнать больше о деталях реализации, вот видео для него.

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

А типичная пользовательская история (подмножество фичи) обычно представляет собой сложную проблему, нам нужно их разбить, и процесс ее разбивки здесь называется постановкой задач.

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

Как программисты, мы, естественно, думаем о проблемах относительно глубоко, например, что, если пользователь вводит какой-то недопустимый текст в поле, что, если сеть нестабильна, как насчет пользователя, который начал заказ в веб-приложении и был прерван, а затем решил продолжить на своем телефоне? Есть много сценариев, которые нужно учитывать, и трудно думать о них всех сразу.

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

Задания

Каждая задача обычно должна следовать принципу S.M.A.R.T,

  • Конкретная — задача должна быть конкретной в отношении того, что должно быть сделано.
  • Измеримый — должны быть какие-то тесты, которые могут проверить успешность задачи.
  • Достижимо — очевидно, мы не можем сделать что-то сверх наших возможностей
  • Актуальность — задача должна быть связана с тем, что мы пытаемся реализовать, а токен входа пользователя не может быть прямой ссылкой на историю со списком продуктов.
  • Time-boxed — мы должны следить за тем, как долго он использовался. Длинная задача может указывать на то, что задача слишком велика или невыполнима.

Так что составить список задач для нашего примера Buy Some Milk с учетом принципов S.M.A.R.T несложно:

  • Визуализирует элемент
  • Отображает несколько элементов
  • Добавляет элемент списка дел
  • Очистите поле ввода после добавления элемента
  • Отмечает элемент как выполненный

2. Напишите тест, который не работает

Итак, первым шагом было бы написать тест, который не работает.

Убедиться, что механизм тестирования работает

Если вы добавляете тест к существующему коду, важно убедиться, что тесты связаны с кодом продукта. Например, бегун слушает __tests__/*.test.tsx, а когда вы добавите Todo.spec.tsx, то он будет проигнорирован. И пока тесты проходят, вы можете быть введены в заблуждение и продолжать делать большие рефакторинги, пока не станет слишком поздно.

Кроме того, одна проверка, которую я всегда делаю (и я знаю, что делают многие другие программисты), — это попытка сломать существующий тест. Например, учитывая, что текущий calculate.test.ts проходит, я изменяю некоторую логику в calculate.ts, чтобы увидеть, не проходят тесты или нет.

И в calculate я изменяю add на:

export const add = (x, y) => x - y;

И если код дает сбой, я знаю, что test и implementation связаны, и я могу улучшить тесты, добавив больше (не забудьте изменить его обратно :)).

Пишите тесты

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

Например, с enzyme у вас может быть такой код:

Но с react-testing-library тесты больше фокусируются на поведении компонента, а не на внутреннем состоянии.

Обратите внимание на API здесь, getByText проверит DOM, чтобы увидеть, есть ли в нем этот контент (точно так же, как это сделал бы реальный пользователь в браузере), а также toBeInTheDocument, фокус смещается на потребителя (а не на разработчика).

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

3. Исправить тест с минимальными усилиями

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

Магические числа, встроенные функции, вложенные if-else и т. д. На данном этапе все это нормально.

Но не останавливайтесь на достигнутом. После того, как вы прошли тесты (или снова прошли), ищите возможности их улучшить.

4. Рефакторинг, если можете

Мартин Фаулер в своей книге Рефакторинг: улучшение дизайна существующего кода дает несколько определений рефакторинга:

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

и

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

Ключевыми моментами здесь являются:

  1. Внесите изменения, не изменяя наблюдаемое поведение
  2. Ряд (небольших) изменений

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

И он также определил 46 рефакторингов во втором издании книги. Если вы еще этого не сделали, пожалуйста, остановитесь здесь и прочитайте. Вас оценят, и вам будут рады.

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

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

После того, как вы довольны рефакторингом кода, вы можете повторно запускать следующую задачу из списка и выполнять шаги 2–4, пока не выполните все задачи.

5. Попросите экспертную оценку

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

Я предпочитаю ознакомительную сессию (5–10 минут), чтобы обсудить предысторию, проблемы и то, как я их исправил. Когда я выполнял пошаговое руководство, я часто получал отличные предложения, которые могли бы сделать код чище и понятнее.

Помимо этих предложений, есть и другие преимущества экспертной оценки:

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

Краткое содержание

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

Если вы сочтете это полезным, вот версия для печати, и вы можете скачать и распечатать ее, если хотите.

Удачи и счастливого TDDing.