Что такое модульный тест

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

Что делает хороший модульный тест

1. Читаемый

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

2. Предсказуемость

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

3. Скорость и масштабируемость

В более крупных проектах вы можете пройти десятки тысяч модульных тестов, время тестирования может увеличиться относительно быстро. При двух секундах на тест и 10 тысячах тестов (10K * 2сек = 5,5 часов) для выполнения полного модульного теста потребуется примерно 5,5 часов. Есть способы увеличить скорость выполнения модульного теста в процессе сборки, увеличить емкость сервера и запустить тесты параллельно. Однако вашим разработчикам по-прежнему необходимо запускать эти тесты локально. Лучший способ сократить время модульного тестирования - это ограничить сложность, а также имитировать любые внешние ресурсы, которые требуются модульному тесту.

Хорошим примером может быть подключение к кластеру MongoDB или AWS Elasticsearch. Если вы создаете новое соединение с каждым модульным тестом, ваш тест должен будет приостанавливаться до тех пор, пока соединение не будет установлено. Предположим, что на одно соединение требуется 3 секунды, а у вас 10 подключений, вы добавите 30 секунд времени работы для подключения к кластеру. Лучшим вариантом было бы кэшировать одно из этих подключений и повторно использовать их. Это займет у вас 3 секунды для каждого набора модульных тестов (который представляет собой просто набор модульных тестов).

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

4. Знайте свои инструменты и фреймворки

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

  1. Как лучше всего решать конкретные проблемы?
  2. Каков самый быстрый и эффективный способ запустить модульное тестирование?
  3. Допускают ли ваши инструменты интеграцию облачных сервисов?
  4. Есть ли какие-то специальные настройки, которые ускорят ваше модульное тестирование?
  5. Фреймворк все еще находится в активной разработке, если нет, готовы ли вы его поддерживать, если это открытый исходный код?
  6. Есть ли сообщество, в котором вы можете задавать вопросы?

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

10 лучших практик модульного тестирования

1. Знайте, что тестировать

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

2. Модульное тестирование или сквозное тестирование

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

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

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

  1. Открывающий оверлей
  2. Скорость, замедление и продолжительность анимации
  3. Проверка, отображаются ли на экране одновременно несколько элементов.
  4. Соответствие цветов руководствам по визуальному стилю
  5. Адаптивные макеты веб-дизайна

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

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

3. Настроить и разобрать

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

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

4. Модульное тестирование в изоляции

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

5. Произведите случайный выбор данных, чтобы предотвратить ложные срабатывания.

У вас есть функция, которую вы тестируете, и вы ожидаете, что переданные вами аргументы вернут определенную строку. Итак, вы жестко кодируете эту строку, и каждый раз, когда вы запускаете модульный тест, она проходит поздравления!

Что происходит, когда вы меняете ввод, получаете ли вы ожидаемые результаты? Имеет ли значение длина струн? Вы даже используете аргументы, которые передаются вашей функции, или вы также жестко кодируете возвращаемое значение?

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

6. Организация модульного теста

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

Например, если у вас есть кнопка обновления,

  1. Аналитика триггеров
  2. Запросить сервисный звонок
  3. Изменяет визуальное состояние кнопки

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

7. Ускорьте свои модульные тесты

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

  1. Не добавляйте таймеры, задерживающие выполнение кода.
  2. Смоделируйте все вызовы внешних ресурсов и сервисы
  3. Не требуйте и не импортируйте большие файлы данных

8. Покрытие кода

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

Глубокая логика и утверждения, которых трудно достичь с помощью uni test, могут пролить свет на возможные неэффективные методы кодирования. Чем ближе вы приближаетесь к приемлемому проценту покрытия вашей команды, тем увереннее вы можете быть уверены в своем коде. Большинство фреймворков модульного тестирования предоставляют возможность выполнять какое-то покрытие кода в вашей кодовой базе.

9. Знай свои пределы

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

10. Рекомендации по стилю модульного тестирования

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

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

Дальнейшее чтение