Разделы портала

Онлайн-тренинги

.
Прогресс регрессионного тестирования
23.10.2024 00:00

Автор: Майкл Болтон (Michael Bolton)
Оригинал статьи
Перевод: Ольга Алифанова

Загляните в свежий Интернет, и вы, скорее всего, найдете Еще Одну Статью про Регрессионное Тестирование, утверждающую, что регрессионное тестирование нужно автоматизировать, потому что это механическая повторяющаяся деятельность.

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

Тестирование и проверки

В словаре Rapid Software Testing тестирование – это процесс оценки продукта путем его изучения через опыт, исследования и эксперименты, что до определенной степени включает вопросы, обучение, моделирование, наблюдения, умозаключения, и т. д. Тест – это частный случай тестирования.

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

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

В чем тут подвох?

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

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

Когда проверка рапортует, что все хорошо, это позволяет верить, что хорошо абсолютно все. Однако совершенно необязательно, что абсолютно все идеально работает вообще везде.

  • Возможно, при поиске в базе данных произошла ошибка. Возвращенная сумма должна возвращать покупки за все предыдущие годы, но в тестовой базе хранятся только данные за прошлый год.
  • Возможно, код проверки сегодня отработал как следует, но содержит баг – верно работает только с указанным нами годом, и упускает проблемы с прочими годами.
  • Возможно, производительность была аховой, но функция «самолечения» фреймворка «исправила» проблему, не сообщив об этом нам.
  • Возможно, пользовательский запрос не был логирован, хотя должен.
  • Возможно, элемент браузера не содержит нужных атрибутов ARIA для людей с ограниченными возможностями.
  • Возможно, боги CSS решили, что результат будет невидим или еле различим, или чем-то перекрыт, или находится за пределами экрана…

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

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

Ответственный тестировщик, создающий проверку, должен:

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

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

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

  • Исследует ситуацию
  • Воспроизводит и локализует проблему
  • Проводит анализ, пытаясь выявить ее причины
  • Решает, где сидит проблема – в коде приложения или в коде проверки, или в окружении, или в неких взаимоотношениях между всеми ними
  • Если это проблема, определяет и решает, значима ли она
  • Если это значимая проблема, определяет и решает, как ее оформить и на кого назначить
  • Собирает сведения, необходимые для подтверждения того, что это проблема, и она значима.

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

Проблемы? Где? Какие? Как их найти?

Где, или как надо искать, чтобы найти проблемы продукта? Хорошо бы посмотреть на продукт с разных точек зрения; смоделировать продукт согласно этим взглядам, а затем покрыть эти модели тестированием. В Rapid Software Testing мы моделируем продукт согласно его элементам или факторам:

  • Структурные элементы продукта
  • Функции, благодаря которым в продукте что-то происходит или меняется
  • Данные, которые продукт принимает, обрабатывает, хранит, выдает и удаляет
  • Интерфейсы, позволяющие контролировать продукт или получить доступ к его данным или состояниям
  • Платформы, от которых он зависит
  • Операции, выполняемые пользователями и администраторами в продукте, и условия, при которых выполняются эти операции
  • Время и его отношения с продуктом

Каким важным для пользователей критериям качества могут угрожать проблемы продукта?

  • Мощность
  • Надежность
  • Удобство использования
  • Харизма
  • Безопасность
  • Масштабируемость
  • Совместимость
  • Производительность
  • Устанавливаемость.

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

  • Поддерживаемость
  • Тестируемость
  • Обеспеченность поддержкой
  • Портируемость
  • Возможность локализации.

Как найти эти проблемы? При помощи тест-техник!

  • Функциональное тестирование – проверьте все, что делает продукт.
  • Доменное тестирование – разделяйте и властвуйте данными.
  • Стресс-тестирование – систематически нагружайте продукт, или морите его голодом, или подставьте ему ножку.
  • Тестирование потоков – делайте много всего последовательно, не перезагружая систему.
  • Тестирование сценариев – разработайте правдоподобные истории о том, как люди могут воспользоваться продуктом или навредить ему, а также о том, на что продукт влияет.
  • Тестирование заявлений – сравните продукт с тем, что о нем говорят значимые люди.
  • Пользовательское тестирование – систематически взаимодействуйте с пользователями продукта или имитируйте их.
  • Тестирование на основе рисков – выявите, что может пойти не так, а затем выполните тесты, чтобы выявить, как могут произойти Плохие Вещи, или не произойти Хорошие.
  • Автоматизированные проверки – используйте машину для взаимодействия с продуктом, сбора данных, применения правил принятия решений, отчетности о результатах, всей алгоритмизированной деятельности.

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

Четыре вида тест-деятельности

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

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

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

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

Новое тестирование

Новое тестирование – это опыт работы, исследование и эксперименты с чем-то, для чего у нас пока что нет рабочей ментальной модели.

Задача нового тестирования – это, очевидно, поиск багов. Менее очевидно, что его предназначение в изучении продукта и того, как его тестировать; в выявлении рисков; в разработке моделей продукта; в обдумывании идей, как тестировать систему глубже и эффективнее. Иногда новое тестирование может убедить нас, что там нет ничего особенно рискованного или опасного.

Новое тестирование интерактивно, и в основном требует присутствия тестировщика. Это никак не запрещает применение и разработку инструментов по ходу дела; использование инструментов естественно и нормально.

Новое тестирование – эвристический процесс ментальной оценки. Оно меняет нас и наше мышление. Оно трансформационно, а не транзакционно. Оно не механистично. Оно не повторяется.

Повторное тестирование

Повторное тестирование – это опыт работы, исследование и эксперименты с чем-то, для чего у нас уже есть рабочая ментальная модель – мы получили ее путем тестирования. Мы часто проводим повторное тестирование, отвечая на какое-то изменение в продукте, но это не обязательно. Мы можем заниматься им, исследуя баг; желая обновить или уточнить свои ментальные модели; распознав новые риски; волнуясь, что мы что-то упустили; стремясь расширить или углубить покрытие.

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

Как и со всеми прочими формами тестирования, повторному можно помочь инструментарием. К примеру, я последнее время развлекаюсь с jq, библиотекой для работы с содержимым JSON-файлов и структур данных. Результаты повторного тестирования могут также помочь найти новые способы применения инструментов, привести к разработке новых или более глубокой работе с имеющимися. Забираясь глубже, я учусь моделировать продукт и покрывать модели тестированием. Возможно, вы хотите посмотреть на примеры моделей покрытия: их можно найти здесь.

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

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

Разработка проверок

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

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

Есть и другой вид кода проверок – формализованные, процедурно структурированные, детерминированные, алгоритмизированные тест-кейсы; «Делай это; делай вот это; наблюдай за результатом. Сравни результат с неким предположительно желательным значением, которое заранее обозначено, найдено или посчитано». Этот вид проверок не нацелен на проектирование продукта – он подтверждает и демонстрирует, что продукт может работать.

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

Где-то по дороге кто-то осознал, что люди плохо подражают машинам, и не так чтобы очень это любят. Если нам нужно механистичное поведение – нажимать на кнопки, делать конкретные наблюдения, сравнивать результаты, - то почему бы не заставить машину этим заниматься? И так «код» сценарных проверок превратился в реальный код, выполняемый машинами.

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

В Rapid Software Testing есть роль «инструментальщика». Это разработчик, кто-то более склонный к роли строителя, создателя, чья цель – «Я сделаю то, что положит конец вашим проблемам!» Задачи инструментальщика включают создание и поддержку кода и инструментов, помогающих тестировщикам – тем, кто более склонен к роли критика, детектива, чей девиз «Я найду проблемы во всем, к чему притронусь, и буду искать очень, очень тщательно».

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

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

Если инструментальщика нет, тестировщики, конечно, могут писать код проверок самостоятельно. Но будьте осторожны! По опыту говорю, создание кода – мощная штука, приносящая большое удовольствие. В это легко погрузиться с головой, это гипнотизирует, овладевает нашим вниманием и стремлениями, и маленькие достижения дают нам маленькие всплески эндорфинов. Счастливое время, пролетающее, пока мы пишем код, может легко задвинуть на задний план изучение и взаимодействие с продуктом. Менее счастливое время разбирательств, как заставить этот долбаный код запуститься, отвлечет нас еще больше.

Как и любая разработка, разработка проверок – непрерывно развивающийся эвристический процесс; это не механистично, и он не повторяется.

Сценарные проверки

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

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

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

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

Регрессионное тестирование

В словаре Rapid Software Testing регрессионное тестирование – это тестирование, мотивированное изменением в уже протестированном продукте – или, иными словами, тестирование, сконцентрированное на риске, связанном с регрессом.

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

Что это значит? Это значит, что сценарные проверки – не единственный тип регрессионного тестирования.

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

Сценарные проверки в регрессионном тестировании

Когда люди думают о регрессионном тестировании, они зачастую сразу перескакивают на прогон существующих, уже написанных проверок какого-либо рода.

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

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

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

Повторное тестирование в регрессионном тестировании

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

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

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

Новое тестирование в регрессионном тестировании

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

Новое тестирование в контексте регрессионного тестирования интерактивно, это эвристический процесс, ведущий к ментальному развитию. Он не механистичен и не повторяется.

Разработка проверок в регрессионном тестировании

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

И опять-таки, разработка проверок, как и любая разработка – эвристический процесс развития; не механистический, не повторяющийся.

Заключение

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

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

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

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

Обсудить в форуме