![](https://habrastorage.org/getpro/habr/upload_files/49b/fe8/c02/49bfe8c02db028ed5a648b64206052a9.png)
Привет. Я работаю в сфере тестирования вот уже 13 лет. За эти годы я встречал разнообразные техники организации автотестов, направленные на увеличение производительности работы и облегчение задач команды, что позволяет освободить ресурсы для других значимых задач. Некоторые из этих методов были эффективны, другие - нет.
В этой статье я хочу обсудить важный вопрос перенимания лучших практик из области разработки ПО. Будут рассмотрены несколько подходов, которые мы и наши коллеги уже с успехом используем, и которые возможно будут полезны и вам. Особое внимание я уделю одному из подходов, поскольку он представляет собой прекрасную основу для оптимизации работы над проектами для специалистов по тестированию, а также платформу для развития профессиональных навыков.
Предыстория. Капля философии, или почему я придерживаюсь идеи чистой архитектуры.
Хорошо это или плохо, но часто, когда мы обсуждаем фреймворки для организации тестов, мы сталкиваемся с подходами, основанными на создании сценариев (скриптов). Согласно этому подходу мы используем определенные тестовые данные, которые передаем и на основе которых запускаем тесты. И это довольно хороший подход - все просто и понятно.
Однако, как и все хорошее в нашей жизни, создание сценариев имеет один серьезный недостаток - его можно использовать только в относительно небольших проектах, которые обладают ограниченным функционалом и не подвергаются частым изменениям.
Но что делать, если проект начинает расширяться или если он изначально построен по модульному принципу? В таких случаях использование скриптов перестает быть уместным. Вам придется столкнуться с проблемами масштабирования, поддержки и повторного использования элементов. Каждый файл потребует пересмотра и/или изменений для соответствия новым требованиям, что является очень трудозатратным процессом (и не всегда эффективным).
Так, создание скриптов в больших проектах далеко не всегда эффективно. Что же делать? По моему мнению, намного проще поддерживать чистую и прозрачную архитектуру наряду с модульным подходом. Модульность обеспечивает применение принципа единственной ответственности, добавляет гибкость и расширяемость к фреймворку. "Повторно используемый" код будет задействован для других компонентов, что позволяет минимизировать лишние трудозатраты.
Еще одним преимуществом чистой архитектуры является хороший, чистый код. Работать с таким кодом в больших проектах намного проще, чем постоянно пытаться разобраться с кодом и понять, что имел в виду тестировщик. Чистая архитектура будет ценна не только для коллег, но и для клиента - их командам будет легче понять ваши тесты.
Экономия времени и ресурсов, доступность и исключение разночтений — это основные причины, по которым я придерживаюсь подхода чистой архитектуры в своей работе.
Какие подходы применимы в тестировании и почему?
Коллеги-разработчики выявили (и продолжают открывать новые) гибкие и масштабируемые подходы - архитектурные паттерны, технологии, техники - которые помогают им легче решать задачи в процессе создания цифровых решений. Этот опыт также предоставляет огромную базу знаний для нас, тестировщиков.
Нет необходимости тратить время на разгадывание того, как решить ту или иную проблему; достаточно обратиться к списку готовых шаблонов и выбрать наиболее подходящий. Ведь уже имеется детальное описание каждого шаблона, характерные задачи и методы решения - почему бы не применить эти знания в практике?
Если заимствование настолько полезно, возможно стоит взглянуть на подходы, которые успешно применяются в архитектуре приложений?
В этой области мы также можем найти множество хорошо разработанных решений, и недостатки которых тщательно проанализированы и хорошо известны. Их можно без особых трудностей адаптировать для наших проектов. Давайте рассмотрим несколько примеров.
Пример первый. API
Хорошим примером "архитектурного" заимствования из мира разработки могут служить запросы API.
В чем заключается суть? Контроллеры - это довольно обычный паттерн для создания API-сервисов. В этом случае у нас есть контроллеры, под которыми расположен слой сервисов, занимающихся обработкой зависимостей сервисов и так далее. Что происходит в тестах? Обычно мы начинаем с создания кода - сначала пишем код непосредственно в теле метода теста, который выполняет API-запрос. Потом мы задумываемся о возможностях его повторного использования. Схема выглядит рабочей, но мы можем облегчить себе задачу, применяя методы из разработки.
Как и наши коллеги-разработчики, мы можем отделить слой контроллеров в наших тестах и вызывать нужные методы оттуда, вместо того чтобы записывать их как код в теле тестового метода. Это даст нам большой плюс в виде возможности повторного использования решений для часто встречающихся проблем в будущем (хотя это может привести к другим трудностям).
Что даст нам заимствование подхода? Например, у вас есть тысяча тестов, которые используют одни и те же запросы. Если что-то изменится, нам больше не нужно вносить изменения во все тесты - достаточно просто изменить один метод в контроллере, который отвечает за конкретный запрос.
Второй пример. Модели предметной области.
Хотя этот подход не является единственно правильным, он мне наиболее близок, так как соответствует моей философии, которая основана на глубокой любви к объектно-ориентированному программированию (ООП).
В чем заключается суть? Как мы, тестировщики, обычно организуем хранение данных? Например, мы можем использовать файлы .csv для параметризации или похожих задач. Или данные часто задаются в классах тестов как отдельные поля. Проблемы такого подхода очевидны: данные при таком хранении не структурированы, не систематизированы, не связаны между собой и не дают понимания общей картины. Конечно, можно открыть конкретный тест и посмотреть на данные, но понять их "природу" может быть трудно.
Вновь стоит отметить, что техники из мира программирования могут упростить наши задачи. В данной сфере присутствуют структуры связанных классов, содержащих поля, дочерние и родительские сущности, типы связей один-к-одному/один-ко-многим и так далее.
Что нам даст заимствование подхода? Модели предметной области предоставляют нам видение общей картины. Открывая объект, мы сразу видим, что это не изолированный объект или данные, висящие в пустоте. Понятно становится его взаимодействие с другими объектами в нашей предметной области (по сути, в бизнесе).
Одинаково хорошо подходящие как для разработчиков, так и для тестировщиков, модели предметной области идеально интегрируются в контекст, создают его и помогают лучше понять, с чем мы имеем дело.
Давайте более внимательно рассмотрим нюансы и преимущества использования моделей предметной области.
Подводные камни или что нужно учитывать, если вы решите использовать подход с моделями предметной области
Чтобы помочь сэкономить время тем, кто решил применить модели предметной области в процессе тестирования, я описал ключевые аспекты, к которым вам следует подготовиться, выбирая этот метод.
Понимание предметной области. Создание системы сущностей, которые правильно настроены и взаимодействуют между собой, является сложной задачей. Это включает в себя серию декомпозиций объектов, скрывающих множество нюансов. Таким образом, мы можем начать декомпозицию с той или иной стороны, что может повлиять на структуру предметной области. К тому же, в процессе мы можем допустить ряд неудачных ошибок, поскольку даже заказчик не всегда может объяснить, как работает та или иная вещь в их бизнесе. Поэтому применение подхода модели предметной области требует хорошего знания предметной области, в которой вы работаете.
Высокая цена ошибки. Если мы допустили ошибку в проектировании, исправление этой ошибки может обойтись дорого. Даже незначительная ошибка может направить вас в совершенно другое русло. И такие отклонения, хоть и могут принести некоторую пользу для развития компетенций команды, имеют свою реальную цену в реальном мире.
Взаимодействие должно быть тщательно продумано. Модели предметной области, которые мы применяем, должны быть тесно интегрированы в нашу инфраструктуру, эффективно взаимодействовать с тестами и укладываться в концепцию наших остальных уровней. К примеру, при работе с API важно понимать, как будут обрабатываться модели предметной области. Схожая ситуация и с UI — важно продумать, как модели предметной области будут применяться в Page Objects. Обратите внимание, что использование моделей предметной области в тестах определяет их структуру (что является плюсом), следовательно, дизайн нижних слоев должен быть адекватно спланирован.
Здесь также существует простор для разнообразных подходов. Модели предметной области могут быть разными и использоваться по-разному в отношении хранения и использования. Для кого-то модели предметной области — это просто данные (и это абсолютно нормально). В таком контексте мы разделяем данные и функциональность наших тестов. То есть модели представляют собой только данные, а тесты выполняют с этими данными определенные действия.
Еще один подход предполагает интеграцию действий в модели предметной области, что ведет к использованию все более распространенных обогащенных моделей предметной области, в которых предметные области не только содержат данные, но и обладают поведением этих данных. Определение способа использования моделей предметной области в той или иной ситуации (как средство для хранения или как полноценный объект, выполняющий делегированные задачи) является ключевым вопросом для команды тестирования.
Это, на мой взгляд, основные тонкости, к которым необходимо быть готовым, когда вы решите использовать модели предметной области для структуризации тестирования. Но если учесть, что эти нюансы так значительны, каковы же будут плюсы?
Преимущества применения моделей предметной области в работе.
Ранее в тексте я уже упоминал ряд преимуществ моделей предметной области для тестирования. В этом разделе я бы хотел подчеркнуть те из них, которые я считаю наиболее значимыми лично для меня.
Ваши тестовые данные отделены от реализации. Модель предметной области всегда отделена от реализации, а слой реализации остается в рамках фреймворка. Таким образом, если происходят изменения на более низком уровне, наши тесты остаются неизменными. Если нам нужно что-то изменить, то только в тех местах, где модель предметной области преобразуется в запрос API (если рассматривать пример с таким типом запроса).
Использование моделей предметной области предоставляет больше возможностей для анализа. Например, после внедрения новой функции или изменения текущей функциональности, нам необходимо анализировать, как наши тесты отреагируют на эти изменения. Здесь модели предметной области снова предоставят нам возможность смотреть на ситуацию с широкой точки зрения - мы увидим не просто какие-то данные в тесте, но и то, как эти данные взаимодействуют с другими объектами. Такой взгляд откроет ряд новых возможностей: мы можем придумать дополнительные сценарии; увидеть граничные случаи, которые оставались вне поля зрения из-за разрозненности данных; выявить конфликты, которые могут возникнуть между моделями, тем самым избежав досадных ошибок.
Бесценные знания и опыт, которые пригодятся во множестве проектов. Применение моделей предметной области позволяет нам получить реальные знания о структуре доменных областей, рассматривать тесты на более высоком уровне, и сознательно работать с объектами и тестовыми сценариями.
Хотя это не все преимущества использования моделей предметной области в тестировании, даже этот перечень для меня весомее возможных рисков и нюансов.
Заключительные мысли
Как видите, изучая опыт коллег и применяя лучшие практики, мы, как тестировщики, можем значительно упростить свою работу. Но в то же время, мы можем сделать свою работу более увлекательной, открывая новые способы решения знакомых проблем и развивая компетенции в ряде смежных областей.
Исследование новых инструментов, объединение старых и новых методик с их дальнейшим использованием в практике превращают хорошего специалиста в профессионала, чья экспертиза ценится и востребована.
Надеюсь, я смог четко изложить свои мысли и взгляды в этом материале. Все описанное здесь не следует воспринимать как окончательное руководство к дальнейшим действиям. Скорее, это рассказ о довольно субъективном взгляде на организацию тестов.
Какие подходы из мира разработки вы используете или использовали? Что сработало, а что нет?
Katasonov
В общем тут можно статью заканчивать читать. На чем основано довольно ложное утверждение? Мы используем Jenkins сценарии в гигантском проекте. Никаких вообще проблем. Более того узнайте у разработчиков что такое live documentation, который они сейчас пытаются внедрять вместо юниттестов. Наши сценарии в том числе и есть спецификация функционал проекта. Да изменения бывают и часто, но это фиксируется падениями тестов и тесты легко поправить если это BDD а не код.
Если вы превращаете тестирование в программирование, то возникает логичный вопрос, а кто будет тестировать ваши тесты?
Вот именно поэтому тесты должны быть максимально декларативными и описаны человеческим языком, а не в виде кучи кода с паттернами.
Iknwpwd
Чёт как-то слишком ультимативненько и узенько. Первый же вопрос, а что в BDD не надо структурировать код, который ниже? Он типа резко становится не относящимся к тестированию? Бред...
Katasonov
Для структурирования кода который под BDD у вас лежит, максимум, что вам необходимо это знать один паттерн программирования: "вынеси это в отдельную процедуру". И таким волшебным способом мы избавляемся махом от ООП, Контроллеров и прочих штук, которые вносят дополнительную сложность и риск возникновения ошибок.