Unit testing. Модульное тестирование для новичков

Денис Бородовский

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

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

Содержание:
1. Что такое модульное тестирование?
2. Модульный тест против интеграционного теста
3. Что делает хороший модульный тест?
4. Почему именно модульное тестирование?
5. Как проводить модульное тестирование
6. Тестирование с помощью пирамиды Майка Кона
7. Методы unit-тестирования
8. Инструменты
9. Разработка через тестирование (TDD)
10. Преимущество модульного тестирования
11. Недостатки модульного тестирования
Заключение

1. Что такое модульное тестирование?

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

Модульное тестирование состоит из трех этапов:

  1. Во-первых, инициализация небольшого фрагмента приложения, которое вы хотите протестировать.
  2. Для этого вызывается метод, применяемый в качестве стимула к тестируемой системе.
  3. Последний этап: наблюдение за поведением проверяемого модуля. Если наблюдаемое поведение соответствует ожиданиям пользователя, то модульный тест проходит. Этот пошаговый процесс также называется AAA (Arrange, Act, Assert).

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

Если тестирование происходит при использовании определенных методов — это модульное тестирование на основе взаимодействия. Пользователи часто путают модульное и интеграционное тестирование. Прежде чем продолжить обзор важно понять эту разницу.

2. Модульный тест против интеграционного теста

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

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

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

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

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

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

Такие тесты:

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

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

4. Почему именно модульное тестирование?

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

  1. Вы сможете исправить дефекты на ранней стадии разработки, сэкономив ресурсы.
  2. Это помогает разработчику быстро разобраться с кодовой базой и быстро внести необходимые изменения.
  3. Хорошие модульные тесты обычно служат проектной документацией.
  4. Модульные тесты можно использовать повторно и при необходимости быстро перенести в новый проект. Вам всего лишь следует немного подправить код, чтобы он снова запустился.

5. Как проводить модульное тестирование

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

  1. Разработчик пишет модульные тесты, чтобы проверить функциональность конкретной части приложения. Они закомментированы и будут удалены позже, после успешного развертывания приложения.
  2. Функция должна быть изолирована, чтобы ее можно было проверить более тщательно. Лучшая практика unit-тестирования — копировать и вставлять код в тестовую среду, вместо работы в естественной среде. Изолированный код помогает выявить и устранить зависимости между тестируемым кодом и пространствами данных.
  3. Существует среда модульного тестирования для разработки автоматизированных тестовых случаев. Эта среда автоматизации помогает писать код и проверяет, правильно ли написан код. Во время выполнения модульных тестов платформа регистрирует статус тестовых случаев. В зависимости от серьезности сбоев структура может остановить последующее тестирование.
  4. Рабочий процесс модульного тестирования разделен на четыре категории: это создание тестовых примеров, обзор, базовый уровень и выполнение тестовых примеров.

6. Тестирование с помощью пирамиды Майка Кона

Ни один разговор о тестировании не обходится без упоминания пирамиды тестов, подробно описанную разработчиком Майклом Коном в его книге «Scrum: гибкая разработка ПО»:

Источник: leeorengel.com

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

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

Определения тестов

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

  1. Модульные тесты — как мы уже с вами разобрали, тестируют наименьшую единицу кода — обычно функцию, класс или структуру данных. Самым важным аспектом модульных тестов является их скорость.
  2. Компонентные тесты — это по сути интеграционные тесты. Их цель — выделить правильную функцию отдельного компонента.
  3. Интеграционные тесты обычно включают в себя тестирование взаимодействия между двумя или более компонентами системы.
  4. Системные тесты — служат для тестирования экземпляра (или части) вашей реальной системы. Обычно они соответствуют конфигурации тестовой среды вашей системы. Эти тесты могут быть дорогостоящими для начальной загрузки и медленными для выполнения.
  5. Manual или браузерные тесты — это тип системных тестов, ориентирующихся на пожеланиях конечного пользователя. Их следует ограничить сценариями тестирования, охватывающими многоэтапные или многостраничные рабочие процессы, которые невозможно эффективно протестировать другими способами.

7. Методы unit-тестирования

Ниже приведены методы покрытия кода при модульном тестировании:

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

8.Инструменты

Существует множество автоматизированных инструментов, помогающих при модульном тестировании. Здесь, для примера, рассмотрим самые популярные из них.

  • Jtest — это плагин IDE, использующий фреймворки с открытым исходным кодом, с управляемыми и простыми действиями в один щелчок — для создания, масштабирования и поддержки модульных тестов. Автоматизация этих трудоемких аспектов модульного тестирования позволяет разработчикам больше сосредоточиться на бизнес-логике и создавать более мощные наборы тестов.
  • Junit — бесплатный инструмент для тестирования, основанный на языке программирования Java. Он предоставляет утверждения для определения различных методов тестирования и проверяет данные, прежде чем вставлять их в фрагмент кода.
  • NUnit — широко используемая среда тестирования, позволяющая писать скрипты вручную. Поддерживает параллельное выполнение тестов.
  • JMockit — снова инструмент тестирования с открытым исходным кодом, позволяющий имитировать API с проверкой и записью синтаксиса.
  • EMMA — это набор инструментов с открытым исходным кодом для анализа и составления отчетов по коду, написанному на языке Java. Предназначен для тестирования методов, строк и базовых блоков, он может обращаться к коду без какой-либо внешней библиотеки.
  • PHPUnit — это популярный инструмент тестирования для программистов PHP. Инструмент позволяет разработчикам использовать предопределенные методы утверждения, чтобы убедиться, что система ведет себя определенным образом.

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

9. Разработка через тестирование (TDD)

Unit-testing при разработке предполагает широкое использование специальных фреймворков. Вот несколько фактов о том, что TDD привносит в мир модульного тестинга:

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

10. Преимущества модульного тестирования

  1. Модульное тестирование упрощает изменение и поддержку кода. Когда написаны хорошие модульные тесты, они могут выявлять проблемы каждый раз, когда код запускается или изменяется.
  2. Unit-тесты можно использовать повторно.
  3. Модульное тестирование ускоряет разработку. Все, что вам нужно — запустить графический интерфейс и предоставить все необходимые входные данные.
  4. Модульные тесты более надежны и в долгосрочной перспективе выполняются быстрее. Усилия, прилагаемые для написания и исправления дефектов во время модульного тестирования, намного меньше по сравнению с усилиями, необходимыми для исправления ошибок во время тестирования системы или приемочного тестирования.
  5. Менее затратное по времени и другим ресурсам.
  6. Модульное тестирование упрощает отладку. Если тест не проходит, последние изменения необходимо снова отладить. Тестирование на более высоких уровнях позволяет сканировать изменения, внесенные за несколько дней, недель, месяцев и т. д.
  7. Такой подход улучшает дизайн кода и позволяет проводить его рефакторинг. В процессе написания тестовых примеров для методов или функций всякий раз, когда изменения вызывают ошибку, ее можно быстро идентифицировать или при необходимости исправить.
  8. Модульные тесты при интеграции также дают равенство сборки.
  9. Разработчики могут понять, какие функции выполняет конкретный модуль, и взглянуть на модульные тесты, чтобы получить базовое представление об API.
  10. Поскольку unit-тесты являются модульными, можно тестировать выбранную часть кода, не дожидаясь завершения другой.

11. Недостатки модульного тестирования

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

Общее правило таково: unit-тестирование следует выполнять в сочетании с другими тестами, чтобы получить более точные результаты.

Правила работы с unit-тестами:

  1. Каждый модуль должен быть независимым. Любое изменение в нем не должно влиять на другие юниты.
  2. Используется для одновременной проверки только одного кода.
  3. Вы всегда должны использовать четкие и последовательные соглашения об именах.
  4. Для каждого модуля должен быть отдельный тестовый пример перед отправкой на реализацию.
  5. Ошибки следует исправить заранее, прежде чем переходить к следующему этапу в SDLC (System/Software Development Life Cycle).
  6. Чем больше кода вы напишете, тем больше у вас будет путей для проверки на наличие ошибок.

Заключение

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

Несколько полезных видеороликов по теме:

 

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023