Это не так сложно, как вы думаете

Введение

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

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

Эта статья будет через призму iOS-разработки.

1. Убедитесь, что рефакторинг кода не нарушает существующую функциональность.

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

2 — Добавляет преимущества при изучении кодовой базы и ожидаемого поведения

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

3 — меньше запускать симулятор

При создании новой функции единственный способ проверить логику — запустить проект. В зависимости от вашей машины и размера проекта, это, казалось бы, небольшое количество времени может сократить вашу эффективность. Это было несколько устранено с введением предварительного просмотра SwiftUI в реальном времени и новых машин Apple M1, но любая экономия времени — это хорошо. Если функция находится на первом экране, это может не показаться проблемой, но представьте себе тестирование экрана, скрытого в иерархии представлений.

4 — поощряет внедрение зависимостей

Внедрение зависимостей — чрезвычайно важная концепция, если вы хотите, чтобы ваш код был модульным и тестируемым. Эта тема довольно обширна и может быть довольно сложной для понимания на начальном этапе, поэтому я просто коснусь основной концепции. Допустим, у вас есть представление, и вам нужно передать другой класс/протокол/перечисление, чтобы заполнить несколько меток. В идеале вы должны передать этот тип через инициализатор. Это внедрение зависимостей в самой простой форме. Чтобы довести до конца суть, вы передаете в это представление класс/протокол/перечисление, потому что оно зависит от его значений.

5 — Заставляет задуматься о контроле доступа

При создании типов я изначально помечаю свойства, методы и т. д. как private. Это дает понять вашим коллегам, что функциональность используется только внутри типа. Если вам нужно прочитать содержимое извне, вы можете использовать private(set). К сожалению, private свойств и методов нельзя увидеть в вашей тестовой цели. Есть несколько приемов, которые вы можете использовать для извлечения private компонентов пользовательского интерфейса, но это тема для другой статьи. Вам нужно будет найти правильный баланс между контролем доступа и тестированием.

Немного честности

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

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

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

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

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