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

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

.
Руководство по рандомизированному тестированию (часть 1)
26.05.2020 00:00

Автор: Питер Хутон (Peter Houghton)
Оригинал статьи
Перевод: Ольга Алифанова

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

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

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

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

Помните ли вы аттракционы на ярмарках, которые вы посещали в детстве? Или, может, вы водили туда своих детей? Тогда вы, конечно, знакомы с ограничением роста – достигли ли вы (к примеру) роста в 1 метр, чтобы покататься на "Адских американских горках"?

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

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

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

Будет ли хороший ответ:

  1. Положительным числом?
  2. Меньше 100?
  3. Исключительно целым числом, или скорее дробным?
  4. Пропорцией другого значения (к примеру, если Х большое число, то Y, скорее всего, маленькое)?
  5. Найден после нескольких секунд обработки?

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

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

If the system behaves 'good', then we might be able to assume it handled those inputs OK, and look at the next set - without too much thought. We know that scenario was probably mostly harmless.

Пример: система вернула 3736,2. Процентное соотношение в этом поле должно быть меньше или равно 100, поэтому что-то могло пойти не так.

Пример: ответ вернулся через 10 мс. Обычно расчет и возвращение ответа занимает 400 мс. Возможно, приложение отдает кэшированный ответ? Соединялось ли оно с базой данных (расположенной в Дублине/Сиэттле/Берлине)? Надо разобраться.

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

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

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


Вот один из моих графиков (предварительно я настроил его для отображения аберраций и игнорирования "хороших" результатов).

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

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

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

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