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

Собираем дом из Лего шаг за шагом

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

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

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

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

Для этого есть две основные категории тестирования: модульные и интеграционные тесты. Позвольте мне провести вас через них, используя аналогию:

Хлебобулочная фабрика

Модульный тест

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

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

Функция 1: проверить, что ингредиент является фруктом/молоком/мукой
Если да, отправить на фабрику
Если не отклонить

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

Функция 2: испечь пирог
взять указанные ингредиенты
выполнить инструкции, чтобы испечь пирог
вернуть фруктовый пирог

Теперь, чтобы фабрика была уверена, что эти функции (они же сотрудники) работают правильно, они присылают аудитора — как вы уже догадались, это ваш юнит-тест. Аудитор вручит ингредиенты, например, клубнику, и проверит, правильно ли сотрудник (функция 1) проверяет ее как фрукт. Или отдаст гриб, чтобы проверить, не откажет ли его сотрудник, как и положено.

Проверки функции 1:

1) Свяжитесь с функцией 1, вставьте фрукт (например, клубнику)
и посмотрите, проверен ли он как фрукт

2) Свяжитесь с функцией 1, вставьте что-нибудь еще (например, гриб
) и посмотрите, не будет ли оно отклонено как фрукт

То же самое относится и к функции 2.

Проверка функции 2:

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

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

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

Интеграционное тестирование

Пока мы только заглянули во «вселенную» фабрики. Теперь давайте включим еще одного игрока. Заказчиком фабрики является магазин хлебобулочных изделий, осуществляющий продажу хлебобулочных изделий конечному потребителю. В мире ИТ это может быть внешний интерфейс веб-сайта или другой внутренний модуль. Теперь у нас есть два модуля, которые общаются друг с другом. Пекарня отправляет ингредиенты на конечную точку фабрики «Выпечка пирога» и получает взамен пирог.

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

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

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

Вы можете спросить сейчас: «В чем разница между модулем и интеграционным тестом?» Ну, во-первых, интеграционный тест проверяет связь между внешним модулем (пекарней) и соответствующей конечной точкой API («Bake-Pie»). Получает ли конечная точка запрос (ингредиенты) и отправляет ли она обратно правильный ответ (фруктовый пирог)? Для сравнения, аудитор модульного тестирования передает ингредиенты непосредственно соответствующему сотруднику.

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

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

Поэтому важно проводить как модульные, так и интеграционные тесты.

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

Кроме того, вы можете использовать модульные тесты как часть Разработки через тестирование (TDD). Этот подход ставит тест перед кодом.

  1. Напишите небольшой тест, который не пройден для той части кода, которую вы собираетесь написать.
  2. Напишите максимально простой код, чтобы пройти тест.
  3. Рефакторинг кода, то есть устранение дублирования и обеспечение требуемого качества кода.

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

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

Статьи серии

использованная литература

О цикле статей «Agile Software Testing — инсайты для нетехнических людей вроде меня»

В это изолированное время я воспользовался шансом узнать больше о тестировании программного обеспечения. Это может быть довольно сложно без технического образования. Поэтому я прочитал книгу Agile Testing Condensed: A Brief Introduction Джанет Грегори и Лизы Криспин и проработал содержание, которое они описывают в книге. Чтобы вам было проще быстро получить наиболее важные сведения, я обобщил свои выводы из книги и некоторых дополнительных источников и хочу поделиться ими с вами в серии коротких статей. Они структурированы по этапам разработки продукта, и вы можете прочитать их по частям, чтобы получить целостный обзор, или выбрать темы, которые вас больше всего интересуют. Я считаю, что это поможет вам, так как помогло мне немного больше понять мир тестирования, не имея технического образования.