Композиционное тестирование: новый подход к качеству IT-продуктов |
04.03.2024 00:00 |
Автор: ООО «Программный Продукт» С развитием и усложнением ИТ- продуктов, стоимость регрессионного тестирования увеличивается, а требования к качеству и надежности программного обеспечения становятся всё более высокими. Мы обнаружили, что традиционные методы тестирования не всегда эффективны для масштабных и многофункциональных систем, поэтому начали применять новые техники. В этой статье мы рассмотрим композиционное тестирование, основанное на комбинаторике и системном анализе, которое значительно помогает в автоматизации процессов регресса. Что за зверь? Композиционное тестирование — вид тестирования, направленный на проверку соответствия системы установленным правилам компоновки и взаимодействия её компонентов. Теперь нагляднее: Под академическим тестированием мы подразумеваем тестирование, при котором тесты (модульные, функциональные, интеграционные, сквозные) проходят атомарно и не зависят от других тестов. Это очень популярный вид тестирования, легко проектируемый и преподаваемый в каждом курсе по автоматизации. Запуская систему, спроектированную с академическим подходом, мы получаем результаты тестов A, B, C, D, которые, скорее всего, были выполнены в изолированной среде и не влияли друг на друга. В то время как при запуске композиционного тестирования мы получаем результаты тестов A и B, причём тест B выполняется на основе данных из теста A. Тестовые случаи для такого подхода генерируются, исходя из разнообразных комбинаций данных, параметров системы и их возможных вариантов. Почему был выбран этот подход?При использовании академического подхода к тестированию мы сталкиваемся с необходимостью тратить значительное количество времени на детальное описание каждого тестового сценария. Кроме того, требуется выделение дополнительных трудовых ресурсов на поддержку и обновление этих тестов. Это, в свою очередь, приводит к сокращению объема тестируемых функциональностей. Но на начальных этапах разработки или для небольших/статичных продуктов такой вид тестирования наиболее продуктивный, простой и дешевый. Пример: В рамках многих проектов нам пришлось отказаться от проведения комплексных E2E (End-to-End) тестов. В некоторых случаях мы также прекратили писать тесты, которые проверяли нерелевантные аспекты, такие как информеры ошибок, и отказались от проверок валидации полей. Эти изменения позволили сделать процесс разработки автотестов более реалистичным и управляемым, избегая необходимости нанимать большое количество тестировщиков. В результате время, необходимое для тестовых запусков, значительно сократилось. Однако следует признать, что это повлияло на общее тестовое покрытие. В контрасте с этим, композиционное тестирование позволяет нам сосредоточиться на разработке и детализации законов поведения системы и проводить регресс глубже. Этот подход требует больше времени на начальном этапе проектирования, но в итоге позволяет существенно сократить время, необходимое на разработку конкретных тестовых случаев. На больших и долгосрочных проектах это гораздо выгоднее. СравнениеДопустим, нужно автоматизировать регресс большого почтового продукта. Рассмотрим, что мы можем проверить с помощью каждой техники тест-дизайна.
Придерживаясь академического подхода, рассмотрим, какие тесты мы можем реализовать, учитывая, что продукт большой, и на этот регресс нельзя тратить много ресурсов. Например, стандартный тест для международной доставки может выглядеть так:
Это типичный тест проверки корректности приема данных по API. Но мы не будем проверять всю функциональность, чтобы не утонуть в тестах и не потратить слишком много времени. В таких случаях мы ограничиваемся, например, тремя тестами (отправка внутри города, междугородняя и международная). Мы отказываемся от тестов валидации полей, так как они усложнят наш тестовый стенд и значительно увеличат время регресса. Но самое важное, мы не сможем повторно использовать этот тест в рамках другого тестирования. В композиционном тестировании подход к созданию тестовых случаев отличается от традиционного. Наша задача — описать возможные значения модулей системы и их взаимодействия друг с другом. Эти данные могут включать в себя разнообразные значения полей, каждое из которых может активировать определенные аспекты системы или оставаться нейтральным, не влияя на другие элементы. Например, в контексте тестирования системы доставки, значение "Москва" в поле города активирует тесты, связанные с доставкой внутри одного города. В то же время другое значение, например "Казань", инициирует тесты междугородней доставки. Аналогично, международные адреса запускают тесты, связанные с международной доставкой. Таким образом, мы больше не тестируем определенный сценарий, мы проверяем возможно ли указанное состояние для системы и не будет ли каких-то неожиданных результатов. Используя тестовые стратегии, такие как тестирование по граничным значениям и классам эквивалентности, можно эффективно выявлять потенциальные проблемы и уязвимости в системе. Однако, особенностью композиционного тестирования является постоянное применение попарного тестирования. Попарное тестирование особенно эффективно в системах с большим количеством взаимосвязанных компонентов и параметров. Оно позволяет выявить неочевидные взаимодействия и конфликты, которые могут возникнуть при определенных комбинациях входных данных. Действительно, на первый взгляд может показаться, что композиционное тестирование требует больше усилий из-за необходимости детального анализа и описания каждого тестового случая. Но в долгосрочной перспективе этот подход оказывается более эффективным и экономичным. Одним из ключевых преимуществ композиционного тестирования является возможность переиспользования тестовых случаев. После того, как функциональность системы описана и протестирована, эти тестовые случаи могут быть легко интегрированы в более сложные end-to-end тесты. Это позволяет не только сэкономить время на разработку тестов, но и повысить их качество, так как они охватывают более широкий спектр сценариев использования. Как перейти на композиционное тестирование?Каждый проект уникален и не факт, что композиционное тестирование подойдет именно вам. Мы выделили основные этапы, которые помогут перейти на новый вид тестирования для больших проектов со множеством шагов и комбинаторик. Переход на динамическую генерацию данных. Как мы уже обсуждали в предыдущей статье на Хабре, динамическая генерация данных играет ключевую роль в современном тестировании. Особенно это актуально при переходе на композиционное тестирование, где важно тестировать систему с разнообразными и реалистичными данными. Использование универсальных шаблонов для генерации данных. Часто наиболее эффективным подходом является создание универсальных шаблонов, которые могут быть адаптированы под различные типы данных, такие как текст, имена, номера документов, телефонные номера и т.д. Однако стоит отметить, что в некоторых случаях универсальный шаблон может быть недостаточен, особенно когда речь идет о специфических или сложных типах данных. Одной из основных трудностей при генерации данных является работа с датами. Даты могут иметь различные форматы, быть связаны с временными зонами и требовать учета високосных годов. Самые сложные — зависимые даты. В таких случаях рекомендуется использовать специализированные инструменты или библиотеки, которые позволяют генерировать даты с учетом всех необходимых параметров. Пример: Пользователь заполняет паспорт, и нам нужно проверить валидность этих данных, например, по дате выдачи. Мы подгружаем дату рождения из БД и проверяем (выдан не ранее 14 лет, не более 20 лет в пользовании, не старше 45 и т.д.). Для такой даты нам потребуется отдельный генератор. Чтобы упростить работу с шаблонами, рекомендуем представлять их в сериализуемом виде. Это позволяет хранить шаблоны в централизованном хранилище и легко импортировать их в различные части тестового фреймворка или системы. Такой подход обеспечивает гибкость и масштабируемость процесса генерации тестовых данных. Трансформация фабрик для комбинаций данных объекта под определенный тестовый случай. Как мы уже обсуждали в статье на Хабре, посвященной библиотеке Combidata, ключевым аспектом является способность фабрик генерировать и комбинировать тестовые данные. Это особенно важно в контексте композиционного тестирования, где требуется гибкость и масштабируемость в создании тестовых сценариев. Основные принципы трансформации фабрик:
Пример: Создание различных вариантов пользовательских профилей для тестирования корректности отображения информации, доступов и взаимодействий с внешними системами. Объединение тестовых сценариев (параметризованные тесты). Основные принципы:
Пример: Допустим, у нас есть система обработки заказов, и мы хотим протестировать ее на различные типы заказов. Вместо создания отдельного теста для каждого типа заказа, мы можем создать один параметризованный тест, который будет принимать различные типы заказов в качестве параметров. Это позволит нам протестировать всю функциональность системы обработки заказов с использованием одного теста, что значительно упрощает процесс тестирования. Формирование сети Петри или древовидной структуры проекта:
Переход на E2E Тесты
Пример: Допустим, у нас есть сложная система обработки заказов с множеством взаимодействующих API-эндпоинтов. Мы можем построить древовидную структуру или сеть Петри, которая будет визуализировать все эти взаимодействия. Затем, используя механизмы обхода, мы можем автоматизированно тестировать различные сценарии взаимодействия этих компонентов, включая различные пути обработки заказов, интеграцию с внешними сервисами и т.д. А подходит ли нам?Точно подходит, если речь идет о тестировании API или о продуктах с обширной комбинаторикой. Возможно, это также подойдет для систем с множеством форм или разветвленной бизнес-логикой. Однако, в других случаях, это может быть не лучшим выбором. Для архитектур продуктов, состоящих из множества атомарных сервисов и с минимальными интеграциями, более подходящим может оказаться академический подход или даже ограничение unit-тестами. Спасибо за внимание! Мы будем очень благодарны, если вы поделитесь опытом о том, как устроена архитектура тестирования в вашем проекте. Какие подходы вы используете и как они работают? Довольны ли вы уровнем тестового покрытия вашего проекта? |