Что такое негативные тестовые сценарии

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

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

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

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

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

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

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

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

В каких случаях требуется негативное тестирование? К примеру:

  1. Пользователь нажал кнопку «ОК», но не ввел данные.
  2. Введенные данные превышают допустимое количество знаков.
  3. Имя содержит числовые значения.
  4. В имени есть специальный символ, а приложение этого не предвидит.
  5. Использованы недопустимые слова.

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

Основные методы написания негативных тестов

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

— Анализ граничных значений;

— Разделение эквивалентности.

Что такое «анализ граничных значений»?

Анализ граничных значений — это процесс тестирования между крайними точками или границами входных значений. Крайние значения (например, Start-End, Lower-Upper, Maximum-Minimum, Just Inside-Just Outside) называются граничными, а тестирование называется «анализом граничных значений». Основная идея этого подхода состоит в следующем — нужно выбрать значения входных переменных на их:

  • Минимуме;
  • Чуть выше минимума;
  • Номинальном значении;
  • Чуть ниже максимума;
  • Максимуме.

Что такое «разделение эквивалентности»?

Входные данные домена делятся на разные классы эквивалентности. Этот метод позволяет взять все возможные тесты и поместить их в классы. Во время тестирования из каждого класса выбирается одно тестовое значение. Если вы тестируете поле ввода, куда можно вводить числа от 1 до 1000, нет смысла писать тысячи тестов для всех действительных входных чисел. Тесты можно разделить на классы согласно трем наборам входных данных.

  1. Класс входных данных для всех допустимых входных данных.
  2. Класс входных данных со всеми значениями за нижним пределом. 
  3. Входные данные с любым значением больше 1000.

Проблемы негативного тестирования

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

Негативное тестирование в действии

Представим следующую ситуацию — у вас есть экран входа в приложение с двумя текстовыми полями. В первое текстовое поле необходимо ввести имя пользователя. Во второе — пароль. К вводу данных есть конкретные требования. К примеру, имя пользователя в первом поле не может состоять только из символов. Кроме того, оно не может оставаться пустым (это же требование распространяется и на второе текстовое поле). Пароль может включать любую комбинацию букв (заглавных или строчных) или цифр от 0 до 9. Использовать другие символы нельзя. Максимальное количество символов для обоих полей — 10.

Как, в таком случае, выглядит негативное тестирование? 

  • Попробуйте ввести имя пользователя, состоящее из цифр и символов или только символов: 123 * _ ;
  • Создайте пароль, включающий специальные символы и пробелы: {^ * &;
  • Оставьте оба поля пустыми;
  • Введите более 10 символов в оба текстовых поля.

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

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

Запись на курс Manual QA

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

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

  • Что такое негативное тестирование
  • Почему тестировщики его не любят
  • Техники негативного тестирования
  • Сценарии
  • Разница между позитивным и негативным тестированием
  • Преимущества и недостатки негативного тестирования

Итак, что такое негативное тестирование

Тестирование в целом — это проверка, работает ли софт должным образом, соответствует ли требованиям заказчика; как софт выдерживает челенджи и нестандартные ситуации.

Негативное тестирование олицетворяет “негативный подход” к тестированию. Его можно назвать “тестированием на сбой” или “тестированием на пути ошибок”. Его цель — найти негативные стороны приложения, путем написания специфического тест-кейса; другими словами, все крутится вокруг того как приложение реагирует на некорректные данные, и в таком подходе есть смысл, как будет видно далее.

Почему тестировщики не любят негативное тестирование

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

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

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

  • Повышает ответственность в команде

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

  • Клиенты довольны

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

Негативное тестирование это вещь, в которую можно и нужно инвестировать, невзирая на возросшие расходы.

Техники негативного тестирования

Далее приведены техники, применяемые при негативном тестировании.

  • Анализ граничных значений

Метод подразумевает написание тест-кейсов в стандартном для тестировщиков виде: проверка значений, выходящих за пределы, например для поля со значениями от 1 до 100.

  • Разделения по классам эквивалентности

Метод проверки функциональности, путем группирования тестовых значений по нескольким “классам эквивалентности”.

  • Угадывание ошибок

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

  • Чеклисты

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

  • Антипаттерны

Если есть паттерны дизайна, то могут быть и антипаттерны. Если паттерн — лучший способ решить проблему, то антипаттерн — решение которое точно не работает. Антипаттерны — идеальный источник негативных тестов.

  • Исследовательское тестирование

Метод, повышающий скиллы тестировщика, и его понимание приложения, в процессе работы. Применяется параллельно с другими тестами. Делает «общую картину» приложения яснее — в каких условиях приложение работает, в каких нет.

  • Небольшая автоматизация

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

  • Фаззинг-тестирование

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

  • Тестирование перехода состояний

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

Сценарии 

Далее потенциальные ситуации, когда случаются (могут случиться) ошибки и крэши:

  • Сбор данных из обязательных полей

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

  • Несооответствие между типом данных и типом поля

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

  • Допустимые границы и лимиты

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

  • Разрешенное количество символов

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

  • Тестирование сессий

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

  • Специфические данные

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

Разница между позитивным и негативным тестированием

“Позитивное тестирование должно проверить, что приложение нормально работает в нормальных условиях. Негативное — в ненормальных”.

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

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

  • Проявляет некорректную обработку ошибок

Позволяет избежать сбоев, вызванных неправильной обработкой ошибок.

  • Идентифицирует слабые места в безопасности

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

  • Поддерживает «чистоту баз данных»

Базы данных будут в отличном состоянии, если в них только корректные данные. Негативное тестирование (почти) гарантирует, что там хранятся только корректные данные.

Недостатки

Негативное тестирование может занимать много времени, и бывает достаточно дорогим процессом.

Когда ручного тестировщика впервые просишь проверить метод REST API, того охватывает паника: «Как это делать? Я вообще почти ничего не знаю про API. Что делать? Как это тестировать?»

Спокойно. Без паники =) Я уже рассказывала на простом языке, что такое API. А сегодня я расскажу о том, как его тестировать. На самом деле почти также, как GUI: в первую очередь это тест-дизайн и придумывание проверок, а потом уже всякие API-штучки. Но и про них не стоит забывать.

Я дам вам чек-лист, к которому вы сможете обращаться потом — «так, это проверил, и это, и это. А вот это забыл, пойду посмотрю!». А потом мы обсудим каждый пункт — зачем это проверять и как.

После теории будет практика! Для неё возьмем метод doRegister системы Users — он находится в открытом доступе, можете дергать по ходу чтения и проверять =) 

Чек-лист проверок

Общий чек-лист:

  1. Правильное тело (пример)

  2. Бизнес-логика: позитив, негатив

  3. Различные параметры (обязательность, работа параметров)

  4. Перестановка мест слагаемых (заголовки, тело)

  5. Регистрозависимость (заголовки, тело)

  6. Ошибки: не well formed xml / json

Где искать параметры:

  • В URL

  • В заголовках

  • В теле запроса

  • Комбинация

Тестирование параметров:

  1. Правильный параметр (из примера)

  2. Обязательность (что, если параметр не указать?)

  3. Бизнес-логика (тест-дизайн)

  4. Регистрозависимость (если параметр текстовый)

  5. Перестановка местами

То есть берём REST-часть и обычную, применяем тест-дизайн, словно это параметр в графическом интерфейсе.

Тестирование заголовков:

  • Заголовки из документации работают (в целом)

  • А если какой-то не передать? (обязательность)

  • А если передать, но неправильно? (текст ошибки)

  • Позитивные тесты по доке

  • Регистронезависимость заголовков

Что смотрим в ответе:

  • Status Code

  • Body

В теле смотрим:

  1. Какие поля вернулись в ответе?

  2. Значения в полях

  3. Текст ошибок 

Поля в ответе нужно:

  • сравнить с ТЗ

  • сравнить между собой SOAP REST 

Кратко прошлись, теперь разберемся в деталях и с примерами.

Содержание

  • Позитив или негатив?

  • В каком порядке тестируем

    1. Примеры

    2. Основной позитивный сценарий

    3. Альтернативные сценарии/a>

    4. Негативные сценарии

    5. Параметры запроса

    6. Остальные тесты

  • Что тестируем в запросе

    1. Заголовки (Headers)

    2. Тело запроса (body)

    3. URL

    4. Тип метода

  • Что тестируем в ответе

    1. Тело ответа

    2. Статус-коды

  • Итоговый чек-лист проверки doRegister

  • Вывод


Позитив или негатив?

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

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

Сначала надо проверить негатив. Потому что разработчики продукта, которые подключают наше API, всегда будут напарываться на грабли. Не прочитали документацию / прочитали криво — получили ошибку.

И нужно, чтобы по сообщению об ошибке они поняли:

— Что они сделали не так

— Как это исправить

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

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

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

Обсудите со своими разработчиками, как им будет удобнее — чтобы вы сначала потыкали “на слом” и прислали очевидные баги, или вдумчиво проверили всё и прислали результат одним файлом. Как им удобнее, так и делайте. 

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


В каком порядке тестируем

1. Примеры в ТЗ

Самое простое, что можно сделать — дернуть пример из документации, чтобы посмотреть, как метод вообще работает. А потом уже писать обвязку в коде.

Это пойдут делать тестировщики, получив от вас новый функционал. И это же сделает разработчик интеграции / другой пользователь API.

Отсюда вытекают следующие выводы:

а) Примеры в документации должны быть! Причем желательно не один, а на каждый интересный кейс. Чтобы на него точно обратили внимание!

б) Примеры тестируем в первую очередь, потому что именно их дернут первыми. И потом будут делать по аналогии.

Практика на примере Users

В Users есть только один пример:

{

    "email": "milli@mail.ru",

    "name": " Машенька",

    "password": "1"

}

Его и попробуем отправить!

  • Тип запроса — POST

  • URL — http://users.bugred.ru/tasks/rest/doregister

  • Тело — из примера

Упс, ошибочка… Читаем её внимательно: 

" email milli@mail.ru уже есть в базе"

В целом логично, раз метод создает нового пользователя, может быть ограничение уникальности. Смотрим в ТЗ, и правда:

Имя и емейл должны быть уникальными

Значит, метод не идемпотентный… Нельзя просто взять пример из ТЗ и отправить не глядя.

Справка

Метод HTTP является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. Корректно реализованные методы GET, HEAD, PUT и DELETE идемпотентны, но не метод POST. © developer.mozilla.org

Нужно взять пример и отредактировать его так, чтобы данные стали уникальными. Можно от руки дописать несколько циферок:

{

    "email": "milli5678@mail.ru",

    "name": " Машенька5678",

    "password": "1"

}

А можно использовать функционал Postman, который позволяет указать рандомные значения — динамические переменные. Пожалуй, мне хватит $randomInt. Но так как я отправляю запрос в JSON-формате, то надо обернуть переменную в фигурные скобки, иначе постман считает её как простой текст:

{

    "email": "milli{{$randomInt}}@mail.ru",

    "name": " Машенька{{$randomInt}}",

    "password": "1"

}

Сработало!

См также: Как понять, что мы отправляли, какую переменную? 

Пример проверили, отлично. Он рабочий, но не идемпотентный, так что его нужно скорректировать под себя. Документация НЕ неправильная, запрос рабочий, если его прогонять на пустой базе в первый раз.

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

И чем больше у вас пользователей, тем больше таких вопросов будет. Заводить ли тут баг на правку документации? Можно предложить дописать в ТЗ как-то так:

Запрос (для проверки запроса исправьте имя пользователя и email, чтобы они были уникальными): …

То есть заранее подсказываем, что надо изменить, чтобы запрос сработал AS IS. Можно было бы и пример с рандомными переменными постмана дать, но тут надо понимать, что через постман его будут дергать тестировщики и аналитики со стороны заказчика.

Разработчики же должны написать код, используя ваш пример. А они тоже любят копипастить))) И если дать пример, заточенный под постман, то к вам снова придут с вопросом, почему ваш пример не работает, но уже в коде. И тут опять или писать около примера, что “$randomInt — переменная Postman, она тут для того-то”, или всё же примеры оставить в покое.

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

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


2. Основной позитивный сценарий

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

В идеале он берет этот сценарий из примера. Если примеров нет, будет дергать метод наобум, как он считает правильным. Знаете, как с новым девайсом — сначала попробовал сам, если не получилось, пошел читать инструкцию.

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

Практика на примере Users

А у нас есть пример, так что основной позитивный сценарий мы уже почти проверили! 

Почему “почти”? Мы проверили, что система вернула в ответе «успешно создалась Машенька562», но точно ли она создалась? Может быть, разработчик сделал заглушку и пока метод в разработке, он всегда возвращает ответ в стиле “успешный успех”, ничего при этом не делая.

Так что идем и проверяем, есть ли наша Машенька в GUI — http://users.bugred.ru/. Ищем поиском — есть!

Проверяем все поля:

  • Емейл правильный, какой мы отправляли.

  • Автор «rest», что логично.

  • Дата изменения — сегодня, что тоже правильно.

Значит, пользователь правда создан! Хотя постойте… Я же выполняла не метод CreateUser, а doRegister. Его основная цель — не создать карточку, а зарегистрировать пользователя в системе. Просто при регистрации карточка автоматом создается, поэтому её тоже зацепили проверкой.

А как проверить, что регистрация прошла успешно? Правильно, попробовать авторизоваться!

Нажимаем «Войти» и вводим наши данные: milli754@mail.ru / 1

Вошли! Ура, значит, регистрация правда сработала. Вот теперь мы закончили с основным позитивным сценарием.


3. Альтернативные сценарии

На самом деле если в ТЗ нет отдельно выделенного сценария использования, то можно объединить пункты “альтернативные сценарии” и “негативное тестирование”, потому что по факту после базового теста мы:

  1. Читаем каждое предложение из ТЗ, «Особенности использования» или как этот раздел у вас называется

  2. Продумываем, как его проверить: как позитивно, так и негативно.

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

Практика на примере Users

Читаем особенности использования:

Пользователь создается и появляется в системе.

Это мы уже проверили. Дальше:

Автор у него всегда будет «SOAP / REST», изменять его можно только через соответствующий-метод.

Автора тоже проверили, но только вот в ТЗ он указан капсом, а по факту создается в нижнем регистре. Это уже небольшой баг, скорее всего документации, так как некритично и проще доку обновить. Сделали заметочку / сами исправили доку, если есть доступ.

А дальше видим, что изменять только только через соответствующий метод. Ага, то есть если создали через REST, менять можно тоже только через REST, через SOAP нельзя. И наоборот. Это и проверим.

Для начала под Машенькой в ГУИ посмотрим, есть ли возможность отредактировать собственную карточку — нету. Ок. Открываем в SOAP Ui WSDL проекта — http://users.bugred.ru/tasks/soap/WrapperSoapServer.php?wsdl, и смотрим, каким методом можно вносить изменения.

Нам вполне подойдет UpdateUserOneField, он обновляет одно любое поле пользователя. А как понять, какие поля есть? Покопаться в документации. В Users описаны не все методы, но есть описание CreateUser, где можно взять названия полей. Допустим, хочу обновить кличку кошки — cat. Получается запрос:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wrap="http://foo.bar/wrappersoapserver">

   <soapenv:Header/>

   <soapenv:Body>

      <wrap:UpdateUserOneField>

         <email>milli754@mail.ru</email>

         <field>cat</field>

         <value>Еночка</value>

      </wrap:UpdateUserOneField>

   </soapenv:Body>

</soapenv:Envelope>

Отправляем, хммммм:

Поле cat успешно изменено на Еночка у пользователя с email milli754@mail.ru

Проверяем в интерфейсе, находим карточку пользователя и жмем “Просмотр” (прямую ссылку давать бесполезно, база дропается каждую ночь, тут только самому создать и посмотреть). Значение обновилось:

Значит, условие из ТЗ не выполнено, можно ставить баг!

А мы пока читаем дальше:

Имя и емейл должны быть уникальными

Раз должны, то будет ошибка в случае неуникальности. А мы решили вынести тестирование негативных сценариев отдельно. Видите, решение тестировать альтернативы отдельно от негативного сразу оказалось не самым удобным — куда лучше просто читать ТЗ и каждый пункт проверять. Так хоть не запутаешься, что проверил, а что ещё нет… Однако в рамках статьи мы всё-таки рассмотрим негативные тесты отдельно. 

Пока же смотрим дальше — а всё, кончилось ТЗ, метод то простенький. Тогда переходим к негативу!


4. Негативные сценарии

По факту это проверка сообщений об ошибках. Смотрим на метод и думаем, как его можно сломать? Сначала бизнесово, а потом API-шно…

С бизнесовой точки зрения очень удобно, когда все ошибки прописывают прямо в ТЗ. Получается руководство к действию! Это можно быть разделение на «Особенности использования» и «Исключительные ситуации», как в Folks (логин для входа тут). Тогда тестируем блок «Исключительные ситуации».

Или вот описание Jira Cloud REST API, выберем в левом навигационном меню какой-нибудь метод, например «Delete avatar». Там есть описание метода, а потом в блоке Responces переключалки между кодами ответов.

Ну так вот все желтые коды — это ошибки. Открываем каждую, читаем «Returned if» и выполняем это условие, очень удобно:

В общем, если есть отдельно про ошибки — класс, проверяем по ТЗ. А потом ещё думаем сами, что там могло быть пропущено.

Плюс проверяем логику ошибок в API, но о ней чуть позже. Сначала бизнес-логика, потом уже серебряная пуля типа well formed json.

Практика на примере Users

Ограничение в ТЗ:

Имя и емейл должны быть уникальными

Для проверки нам надо сделать неуникальным:

  1. имя

  2. емейл

  3. оба поля сразу

Можем взять за основу наш исходный запрос, который 1 раз создался:

{

    "email": "milli754@mail.ru",

    "name": " Машенька562",

    "password": "1"

}

И варьируем его

1. Уникальный емейл, дубликат имени

{

    "email": "milli{{$randomInt}}@mail.ru",

    "name": " Машенька562",

    "password": "1"

}

2. Уникальное имя, дубликат емейл

{

    "email": "milli754@mail.ru",

    "name": " Машенька{{$randomInt}}",

    "password": "1"

}

3. Дубликаты сразу имени и емейл

{

    "email": "milli754@mail.ru",

    "name": " Машенька562",

    "password": "1"

}

И смотрим на ответ. Понятно ли нам из сообщения об ошибке, что именно пошло не так? А статус-код соответствует типу ошибки?


5. Параметры запроса

На входе мы передаем какие-то параметры. И теперь нам нужно взять каждый параметр и проверить отдельно. Как проверяем:

  1. Обязательность

  2. Перестановка мест слагаемых

  3. Бизнес-логика

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

Вот у вас есть параметры запроса. Как их проверять? Если вы впали в ступор сейчас, то просто представьте себе, что это не API, а GUI. Что у вас в интерфейсе есть форма ввода с этими полями? Как будете тестировать? Вот ровно так и тестируйте, выкинув разве что попытку убрать ограничение на клиенте (снять с поля maxlenght).

Практика на примере Users

По ТЗ входные параметры:

Имя параметра

Тип

Обязательный?

Описание

email

строка

да

email пользователя

name

строка

да

имя пользователя

password

строка

да

пароль

Тестируем каждый параметр в отдельности. И тут, как и в GUI, надо понимать:

  • Есть ли какие-то проверки у поля? Проверяется ли email по маске email-а? Имя выверяется по справочникам? Или это “просто строка, как прислали, так и сохранил?”

  • Куда данные идут дальше, где отображаются? В приветствии, в отчете, в личном кабинете, где?

  • Как они потом используются? На емейл придет письмо?

email

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

Можно взять за основу вот этот чек-лист, но часть проверок скомбинировать

  1. Корректный существующий email, куда может прийти почта — подставляем свой (начинаем всегда с корректного)

  2. Верхний регистр, цифры в имени пользователя и доменной части — TEST77@mail9.ru

  3. Email с дефисами и нижним подчеркиванием — test_user-1@mail_test-1.com

  4. Email с точками в имени пользователя и парой точек в доменной части — test.user@test.test.test.ru

А дальше идут интересные тесты, которые по идее должны падать, но упадут ли в Users, есть ли там такие проверки?

  1. Email без точек в доменной части — test@mailcom

  2. Превышение длины email (>320 символов)

  3. Отсутствие @ в email — testmail.ru

  4. Email с пробелами в имени пользователя — test user@mail.ru

  5. Email с пробелами в доменной части — test@ma il.ru

  6. Email без имени пользователя — @mail.ru

  7. Email без доменной части — test@

  8. Некорректный домен первого уровня (допустимо 2-6 букв после точки: .ru) — test@mail.urururururu

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

{

    "email": "test@mailcom",

    "name": " Машенька{{$randomInt}}",

    "password": "1"

}

И сервер отвечает — некорректный емейл!

Так что проверки на емейл нужны, особенно — на некорректный.

name

Имя можно тестировать по разному. Если по нему определяется пол, тесты будут одни, если предлагаются подсказки, другие, а если это простая строка — третьи.

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

Поэтому закапываться в “а теперь проверим мужское имя, и женское, и…” смысла нет.. Так что наша задача — проверить:

  • Что это правда простая строка и туда влезет всё, что можно

  • Максимальную длину изучить

Ну и начинаем с позитивного теста. Итого получаем:

  1. Простое имя типа “Ольга”

  2. Имя с разным регистром, разными буквами и спецсимволами (все спецсимволы можно перечислить) — если есть ограничение по длине, разобьем на разные тесты

  3. 1 000 символов — ищем верхнюю границу, если она есть. Заодно смотрим, как это выглядит в интерфейсе и корректируем тест.

  4. 1 000 000 символов — ищем технологическую границу

Обратите внимание на то, что мы вроде как тестируем API-метод, но после его выполнения лезем в графический интерфейс и проверяем, как там выглядит результат нашего запроса.

А всё почему? Потому что нет абстрактных методов, которые делают “ничего”, просто отправляются. Они все зачем-то нужны. В нашем случае — чтобы создать пользователя в системе. И важно понимать, а что будет потом с нашими данными? Будут ли они нормально отображаться в интерфейсе? Ведь если нет, то надо ставить ограничение на API-метод.

Поэтому помните, что API и GUI идут рука об руку, а не живут в разных мирах.

Password

На пароле тоже никаких ограничений нет — мы это знаем, потому что уже отправляли запрос с паролем “1”. Вот если бы были всякие “нужны заглавные буквы” и прочее, мы бы провели тесты “а если пароль ненадежный” и посмотрели на качество сообщения об ошибке, а так тесты будут как у имени:

  1. Обычный пароль типа 1

  2. Смесь из разных регистров, разных букв и спецсимволов — если есть ограничение по длине или составу, разобьем на разные тесты

  3. 1 000 символов — ищем верхнюю границу, если она есть. Заодно смотрим, как это выглядит в интерфейсе и корректируем тест.

  4. 1 000 000 символов — ищем технологическую границу


6. Остальные тесты

А дальше мы уже идем по специфике API:

  • Перестановка мест слагаемых (заголовки, тело)

  • Регистрозависимость (заголовки, тело)

  • Well formed xml / json

На конкретных примерах мы остановимся подробнее в следующих разделах. Просто важно не забывать про эти тесты. Этим и отличается API от GUI — тут нельзя снять границу из серии “убрать maxlenght”, зато можно и нужно проверить особенности API запросов.


Что тестируем в запросе

Заголовки (Headers)

Заголовки должны где-то обрабатываться:

— на сервере;

— на клиенте;

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

Так что разработчики используют «Принцип меньшего зла»: заголовок или кем-то обрабатывается, или он вообще не нужен.

Если заголовка нет:

— используется дефолтный, прописанный в коде;

— он вообще не нужен;

Язык должен указываться всегда, иначе непонятно, как вернуть ответ от сервера. Но разработчик может в код зашить русский язык, и тогда даже если вы передадите заголовок «Accept-Language: en-US», то ответ получите на русском.

Почему? Потому что разработчик игнорирует этот заголовок, он его не считывает из запроса в принципе. Его право =) 

Возможные ситуации, которые надо проверить

Заголовок не передан, как система реагирует:

— выдает ошибку → понятно ли, что мне надо сделать?

— применяет поведение по умолчанию (если язык не передан, используй русский)

Заголовок передан:

— верно

— неверно → какая ошибка?

Плюс регистрозависимость. Согласно спецификации, все заголовки должны быть регистронезависимы. И неважно, как я их передаю. Могу в CamelCase (первая буква большая, остальные мелкие), могу в верхнем регистре, причем как значение заголовка, так и его название, могу как-то ещё:

  • Accept: application/json

  • Accept: APPLICATION/JSON

  • ACCEPT: application/json

  • ACCEPT: APPLICATION/JSON

  • ACcePT: APPlicATIon/JSon

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

Был случай у моих коллег — заголовок проверили, всё работает. Но проверили по доке, прислали значения «как указано». Вот Accept может быть (как передаются входные данные):

  • application/json

  • application/xml

А потом пользователи приходят и жалуются на ошибки «у вас плохой заголовок». При том, что заголовок они отправили правильный. Начали разбираться — запрос идет не напрямую на сервер, он проходит через прокси Nginx. А Nginx меняет заголовки на upper case: ACCEPT: APPLICATION/JSON.

Система к такому не готова, она ищет «Accept», не находит его и выдает ошибку. А переданный заголовок игнорирует. Так что проверять регистр — надо!

Итого — тестирование заголовков в API

  • Заголовки из документации работают (в целом)

  • А если какой-то не передать? (обязательность)

  • А если передать, но неправильно? (текст ошибки)

  • Позитивные тесты по доке

  • Регистронезависимость заголовков

Практика на примере Users

В документации вообще ничего не сказано про заголовки. Поэтому проверяем, можно ли отправить сообщение без них. Идем на вкладку Headers и снимаем все галки, если они по каким-то причинам там стояли. Запрос сработал успешно:

Но обратите внимание, что в постмане есть ещё скрытые заголовки (hidden):

Это те заголовки, что генерирует сам постман. По сути постман — это клиент, помогающий нам отправить запрос на сервер. И у него есть какие-то свои фишечки, ограничения, заголовки опять же. 

Можно нажать на это сообщение “(цифра) hidden” и раскрыть этот список (а потом всегда можно нажать на кнопку “hide hidden”:

Это некий стандарт, дефолтные значения по умолчанию. Тот же Cache-Control, раз вы его не передаете, по факту он вам не нужен, то есть как если бы вы указали “no-cache”.

Но учтите, что если снять тут все-все-все галки, система может выдать ошибку:

Плохо ли это? Стоит ли заводить баг “в документации сказано, что можно без заголовков, а так не работает” — нет. Для начала попробуйте отправить запрос через curl и посмотрите на результат.

Помните, что Postman — это всё-таки клиент, у которого есть свои навороты. Так что пусть он их накручивает сколько влезет, эти хидден-заголовки тестировать особо не надо. А вот послать хотя бы разок честный curl — надо!

Так что прячем hidden-заголовки и проверяем без них в этом пункте. Да, doregister без заголовков работает, всё ок.


Тело запроса (body)

Что мы тут тестируем:

  1. Правильное тело (пример)

  2. Различные параметры (обязательность, работа параметров)

  3. Бизнес-логика

  4. Ошибки: бизнес-логика

  5. Перестановка мест слагаемых

  6. Регистрозависимость

  7. Ошибки: не well formed xml / json

Пункты 1-4 мы уже обсудили выше. Идем по ТЗ и каждую строчку изучаем и проверяем. 

Перестановка мест слагаемых

Это как раз особенность API, поэтому очень важно её проверить. Бизнес-логика и проверки “а что можно ввести в такое-то поле” одинаковы для GUI и API, а вот переставить поля местами в графическом интерфейсе не получится.

При этом в API это сделать проще простого. Мы ведь передаем пары “ключ-значение”. Что будет, если мы попробуем поменять их местами? 

В идеале ничего не случится, потому что принимающая система должна из запрос цеплять информацию именно по названию ключа, а не делать “select *” и потом говорить “для первого поля из запрос проверь то, для второго сделай это…”. 

Ведь потом изменится входной запрос и у нас вся интеграция сломается! А это нехорошо… Так что смотрим как система реагирует на перестановки.

Регистрозависимость

Вы же помните о том, что регистронезависимость не появляется из воздуха? Её делает разработчик. Поэтому и проверить “как ведет себя система” — тоже надо. И в заголовках, и в теле, и в параметрах URL —  вообще везде, где есть символы.

Ошибки в ответе от сервера

Всегда обязательно изучаем ошибки. Помимо ошибок в бизнес-логике есть ещё неправильно составленный запрос. То есть не well formed. Пробуем такой послать и смотрим на адекватность ошибки

См также:

Правила Well Formed XML

Правила Well Formed JSON

Практика на примере Users

По бизнес-логике мы уже прошли, теперь пойдем по API-части:

1. Перестановка мест слагаемых

В json пробуем перестановку:

{

    "name": " Машенька{{$randomInt}}",

    "email": "test{{$randomInt}}@mail.com",    

    "password": "1"

}

Ура, работает! А как насчет form-data? Тоже всё ок, это хорошо:

2. Регистрозависимость

Мы уже поняли, что в Users регистронезависимости может и не быть. Поэтому проверим на одном поле для начала. И не email, а то с ним может быть ложная уверенность в корректной ошибке:

{

    "email": "test{{$randomInt}}@mail.com",  

    "NAME": " Машенька{{$randomInt}}",   

    "password": "1"

}

Запрос не сработал, увы: «Параметр name является обязательным!»

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

Но мы, по крайней мере, получили информацию по работе системы.

3. Well formed

У нас на входе json, смотрим его правила:

  1. Данные написаны в виде пар «ключ:значение»

  2. Данные разделены запятыми

  3. Объект находится внутри фигурных скобок {}

  4. Массив — внутри квадратных []

И пытаемся сломать. Вообще самая частая ошибка — это запятая после последней пары «ключ:значение». Мы обычно скопипастим строку из середины (вместе с запятой), поставим в конец объекта, а запятую удалить забудем. Получится как-то так:

{

    "email": "test{{$randomInt}}@mailcom",

    "name": " Машенька{{$randomInt}}",

    "password": "1",

}

Отправляем такой запрос. М-м-м-м, ответ как-то не очень:

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

Попробуем другие способы сломать формат:

— не в виде пар “ключ:значение”

{

    "email": "test{{$randomInt}}@mail.com",

    "name": " Машенька{{$randomInt}}",

    "password"

}

Ответ будет такой же — «Параметр email является обязательным!»

Заметьте, что если мы “сломаем” так email, будет ложное ощущение, что система работает хорошо и правильно дает подсказку. А на самом деле нет… 

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

— данные не разделены запятыми

{

    "email": "test{{$randomInt}}@mail.com"

    "name": " Машенька{{$randomInt}}"

    "password": "1"

}

— объект в квадратных скобках, а не фигурных

[

    "email": "test{{$randomInt}}@mail.com",

    "name": " Машенька{{$randomInt}}",

    "password": "1"

]

Ответ везде одинаковый — «Параметр email является обязательным!»

Не очень хорошо, в ожидаемый результат чек-листа проверок мы запишем что-то более «правильное» =)) Например, ошибка 400 и сообщение «Не well formed json в запросе».


URL

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

Тестируем точно также, как если бы параметр был в теле:

  1. Правильный параметр (из примера)

  2. Обязательность (что, если параметр не указать?)

  3. Бизнес-логика (тест-дизайн)

  4. Регистрозависимость (если параметр текстовый)

Практика на примере JIRA

Почему не на примере Users? А потому что в методе doRegister нет параметров, которые передаются в URL. Да и вообще в Users их нету, там даже get через POST сделан, но сейчас не об этом…

Поищем примеры в Jira Cloud REST API. Например, метод «Get Issue», вот какой у него URL:

GET /rest/api/3/issue/{issueIdOrKey}

Мы передаем в URL или id задачи, или её ключ. Условно говоря, это или что-то типа “13005” или “TEST-1”. 

И вот тут мы уже можем развернуться!

Правильное значение

Базовый позитивный тест, что метод в целом работает. Вызываем обязательно и так, и так:

  • 13005

  • TEST-1

Обязательность

Попробуем не передать параметр:

/rest/api/3/issue/

/rest/api/3/issue

Тест-дизайн

Тут стоит подумать в тему состояний объекта. Пробуем получить:

  • Свежесозданную задачу

  • Несколько раз измененную / отредактированную

  • Заполненную по минимуму / по максимуму

  • В разных статусах

  • Закрытую

  • Удаленную

  • Не существующую (такого номера ещё нет — это отличается от “он есть в базе, но задача была закрыта”)

Регистрозависимость

При передаче issueId этот пункт не проверить, цифры сами по себе регистронезависимы. Но если мы передаем задачу через Key, то это уже символы. Значит, проверка актуальна:

/rest/api/3/issue/test-1
/rest/api/3/issue/TEst-1

Тип метода

Что будет, если мы “подменим” тип запроса?

POST → GET (совсем разные типы запросов)

POST → PUT (похожие типы)

Как система отреагирует? Она может или отработать “словно так и надо”, или выдать ошибку. И тут следим за тем, чтобы ошибка была внятной и понятной.

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

Если бы система сразу падала, то на первичной интеграции пришлось бы поднапрячься побольше, зато дальнейшие переходы были бы бесшовными. А когда уже всё в продакшене, это будет стопить обновление релиза. Так что может, лучше заранее начать ловить за руку “ты мне какой-то треш” шлешь?

Практика на примере Users

Меняем в запросе тип метода с POST на GET — а ему всё равно, успешно!

Нельзя сказать, что это прям вау-поведение, но для Users это нормально =)


Что тестируем в ответе

Тело ответа

Чек-лист проверки:

  1. Какие поля вернулись в ответе?

  2. Значения в полях

  3. Текст ошибок 

Поля в ответе нужно:

  • сравнить с ТЗ

  • сравнить между собой SOAP REST 

Если у нас есть ТЗ — то всё понятно. Читаем, как должно быть, проверяем, как есть на самом деле. Смотрим на то, что все поля из требований вернулись, и что в них правильное значение. А то вдруг я сохраняю имя “Оля”, а там всегда сохраняется “Тестовый”… Очень удобно сразу автотесты писать в том же постмане, если отдельного фреймворка нет — идем по ТЗ и каждое поле выверяем.

Если ТЗ нет, то уже сложнее. Ищем «хранителя информации», расспрашиваем, проверяем, как работает на самом деле. Думаем, есть ли проблемы в текущем поведении. Нет? Ок, значит, так и надо.

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

См также:

Каким должно быть сообщение об ошибке

Сообщения об ошибках — тоже документация, тестируйте их!

Если у вас в системе два интерфейса — SOAP и REST, нужно проверить оба. Обычно они должны быть идентичны. Да и в коде это обеспечивается условно говоря двойной аннотацией “сделай и soap, и rest сгенери”, разработчик не дублирует всю функциональность дважды, а просто “включает” API.

В таком случае действительно всё будет работать идентично, кроме пустых полей в ответе. Что будет, если какое-то поле не заполнено? Может легко быть такая ситуация: 

— SOAP возвращает пустые поля;

— REST нет.

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

К тому же в SOAP всегда есть схема WSDL, где указаны обязательные поля. Значит, они будут возвращаться в ответе. В ресте же схема WADL необязательна, да и там любят придерживаться принципа минимальных чернил, лишнего не выводить.

В общем, проверьте обязательно, как методы срабатывают на:

  • Отсутствие данных на входе (поле не пришло вообще / пришло пустое)

  • Пустые поля на выходе

Если по разному, то это должно быть описано в доке!

Практика на примере Users

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

Как так вышло? Очень просто. Для реста набор полей согласовали, разработчик сделал. Потом я сказала, что хочу ещё и SOAP. А там нужна схема WSDL, разработчик с ней особо не парился. Есть сущность “user”? Ну её и вернем в ответе. А в сущности как раз много полей… 

Мне не критично, так что менять не стали, да и вообще отличный пример «да, и так бывает» же! =))

Ок, давайте теперь посмотрим на особенности API, ведь всю бизнес-логику перетестировать в SOAP смысла нет, она должна совпадать… Ну разве что вы совсем не верите своим разработчикам… Или кейсы очень важные. А так — бизнес-логику смотрим один раз, а потом переходим в особенностям API.

Перестановка мест слагаемых

Поменяем местами name и email — ой ёй ёй!

Система пишет «Некоректный  email Имечко 666». Это значит, что она ориентируется не названия полей, передаваемые в тегах, а на их порядковых номер. И это ОЧЕНЬ ПЛОХО, на такое стоит идти ставить баг. 

Тем более обоснование у нас есть — неединообразно работает. REST вот от перестановки не зависит, и SOAP не должен.

А ещё слово «Некоректный» написано неправильно, там должно быть две буквы “р”. Проверяем в REST, посылая заведомо плохой емейл — да, и там ошибка. Надо бы исправить. Текстовку ошибок вычитываем внимательно!

Регистрозависимость

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

<EMAIL>ggg55555@mail.com</EMAIL>

Работает!

А вот теперь попробуем разный регистр внутри тегов (в json такую проверку не сделать, это особенно XML, дублирование названия поля):

<EMAIL>ggg55555@mail.com</email>

Не работает — Bad Request. Чтож, вполне логично.

Well formed XML

Что, если сломать XML? Скажем, оставить закрывающий тег «/email» без второй угловой скобки:

     <wrap:doRegister>

         <email>ggg5555@mail.com</email

         <name>Имечко 666</name>

         <password>1</password>

      </wrap:doRegister>

Возвращается ошибка 

<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Bad Request</faultstring>

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


Статус-коды

Разработчик может использовать стандартные коды ответов,

  • 2хх — все хорошо

  • 4хх — ошибка на клиенте (в запросе)

  • 5хх — ошибка на сервере

А может придумать свои:

  • 570 — пустой ответ на поиск;

  • 571 — нашли одного ФЛ;

  • 572 — нашли несколько ИП;

  • 573 — нашли только ИП;

Разработчик может даже перекрыть стандартные:

400 — Bad Request

400 — Internal Server Error

Но так лучше не делать =))) Просто знайте, что возможность такая имеется.

Если разработчик ленивый и не настроил коды, то вы будете огребать на любую ошибку стандартный код: 400 Bad Request. Неверный заголовок? Ошибка 400. Неверное тело? Ошибка 400. Проблемы в бизнес-логике? Ошибка 400… Ну и как тут разобраться, что именно надо исправлять?

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

Поэтому статус-код проверяем всегда, обращаем на него внимание. Ну а если в методе собственные статусы (как, например, в методе MagicSearch)

Практика на примере Users

На статус надо было обращать внимание всегда, чтобы не дублировать снова все тесты. Но сейчас просто дернем “хороший” и “плохой” запросы.

Хороший — статус 200, всё ок:

Плохой — ой, статус снова 200, хотя мы видим сообщение об ошибке:

Нехорошо! На это надо ставить баг.


Итоговый чек-лист проверки doRegister

Помним, что в первую очередь проверяем бизнес-логику. А потом уже всякие API-штучки, куда входят:

  • Регистрозависимость

  • Перестановка мест параметров

  • Well formed запрос

Базовый тест

Базовый тест тщательно выверяет каждое поле из “корректного” ответа. Проверяет, как вызов API-метода влияет на отображение в GUI… Поэтому его пропишем текстом, а остальные тесты соберем в табличку.

1. Проверка примера из ТЗ (но имя и емейл меняем на уникальные)

{

    "email": "milli{{$randomInt}}@mail.ru",

    "name": " Машенька{{$randomInt}}",

    "password": "1"

}

ОР: 

1. Статус 200

2. В ответе следующий набор полей:

"name": " Машенька562", (то имя, что мы отправили)
"avatar": "http://users.bugred.ru//tmp/default_avatar.jpg", (в этом методе всегда такой урл стандартной аватарки)
"password": "4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a",
"birthday": 0,
"email": "milli754@mail.com", (тот емейл, мы мы отправили)
"gender": "",
"date_start": 0,
"hobby": ""

3. Пользователь добавлен в общий список. Проверяем через GUI — http://users.bugred.ru/. Ищем поиском — есть!

Проверяем все поля:

  • Емейл правильный, какой мы отправляли.

  • Автор «rest», что логично.

  • Дата изменения — сегодня, что тоже правильно.

4. Под пользователем можно войти в систему — нажимаем “Войти”, вводим емейл из запроса, пароль из запроса, проверяем авторизацию. 

Остальные тесты 

Бизнес-логика из ТЗ

Уникальный емейл, дубликат имени

{

    «email»: «milli{{$randomInt}}@mail.ru»,

    «name»: » Машенька562″,

    «password»: «1»

}

ОР: Статус 400

В теле ошибка: «name (переданное имя) уже есть в базе»

Уникальное имя, дубликат емейл

{

    «email»: «milli754@mail.ru»,

    «name»: » Машенька{{$randomInt}}«,

    «password»: «1»

}

ОР: Статус 400

В теле ошибка: «email (переданный email) уже есть в базе»

Дубликаты сразу имени и емейл

{

    «email»: «milli754@mail.ru»,

    «name»: » Машенька562″,

    «password»: «1»

}

ОР: Статус 400

В теле ошибка: «email (переданный email) уже есть в базе»

Параметр email

Корректный существующий email, куда может прийти почта — подставляем свой (начинаем всегда с корректного)

Успешный запрос

Верхний регистр, цифры в имени пользователя и доменной части — TEST77@mail9.ru

Успешный запрос

Email с дефисами и нижним подчеркиванием — test_user-1@mail_test-1.com

Успешный запрос

Email с точками в имени пользователя и парой точек в доменной части — test.user@test.test.test.ru

Успешный запрос

Email без точек в доменной части — test@mailcom

Статус 400, ошибка «email некорректный»

Превышение длины email (>320 символов)

Статус 400, ошибка «email некорректный»

Отсутствие @ в email — testmail.ru

Статус 400, ошибка «email некорректный»

Email с пробелами в имени пользователя — test user@mail.ru

Статус 400, ошибка «email некорректный»

Email с пробелами в доменной части — test@ma il.ru

Статус 400, ошибка «email некорректный»

Email без имени пользователя — @mail.ru

Статус 400, ошибка «email некорректный»

Email без доменной части — test@

Статус 400, ошибка «email некорректный»

Некорректный домен первого уровня (допустимо 2-6 букв после точки: .ru) — test@mail.urururururu

Статус 400, ошибка «email некорректный»

Параметр name

Простое имя типа “Ольга”

Успешный запрос

Разный регистр, буквы и спецсимволы:

Mixa1234567890`-=[];’/.,~!@#$%^&*()_+}{:”?><|Ё_+ХЪ/ЖЭБЮ,ёхъ-=.

Успешный запрос

1 000 символов — ищем верхнюю границу, если она есть. Заодно смотрим, как это выглядит в интерфейсе и корректируем тест.

Успешный запрос

1 000 000 символов — ищем технологическую границу

Ошибка 400 — «Имя слишком длинное. Максимальная длина (такая-то)»

Параметр password

Обычный пароль типа 1

Успешный запрос

Разный регистр, буквы и спецсимволы:

Mixa1234567890`-=[];’/.,~!@#$%^&*()_+}{:”?><|Ё_+ХЪ/ЖЭБЮ,ёхъ-=.

Успешный запрос

1 000 символов — ищем верхнюю границу, если она есть. Заодно смотрим, как это выглядит в интерфейсе и корректируем тест.

Успешный запрос, пароль обрезается до X символов

1 000 000 символов — ищем технологическую границу

Успешный запрос, пароль обрезается до X символов

Тело сообщения (body)

Перестановка мест слагаемых в json

{

    «name»: » Машенька{{$randomInt}}«,

    «email»: «test{{$randomInt}}@mail.com»,    

    «password»: «1»

}

Статус 200, корректный ответ

Перестановка мест слагаемых в form-data

Статус 200, корректный ответ

Меняем регистр у любого параметра:

{

    «email»: «test{{$randomInt}}@mail.com»,  

    «NAME»: » Машенька{{$randomInt}}«,   

    «password»: «1»

}

Статус 200, корректный ответ

Меняем в запросе тип метода с POST на GET

Статус 400, ошибка «Неправильный тип метода, нужно использовать POST»

Well formed json

Запятая после последней пары «ключ:значение»:

{

    «email»: «test{{$randomInt}}@mailcom»,

    «name»: » Машенька{{$randomInt}}«,

    «password»: «1»,

}

Статус 400

В теле ошибка: «Не well formed json в запросе»

Запрос не в виде пар “ключ:значение”, у пароля убираем значение:

{

    «email»: «test{{$randomInt}}@mail.com»,

    «name»: » Машенька{{$randomInt}}«,

    «password»

}

Статус 400

В теле ошибка: «Не well formed json в запросе»

Данные не разделены запятыми

{

    «email»: «test{{$randomInt}}@mail.com»

    «name»: » Машенька{{$randomInt}}«

    «password»: «1»

}

Статус 400

В теле ошибка: «Не well formed json в запросе»

объект в квадратных скобках, а не фигурных

[

    «email»: «test{{$randomInt}}@mail.com»,

    «name»: » Машенька{{$randomInt}}«,

    «password»: «1»

]

Статус 400

В теле ошибка: «Не well formed json в запросе»


Вывод

Тестирование API — это не страшно! По факту это всё то же самое, что в GUI + дополнительные тесты. В интерфейсе нельзя подвигать местами поля или изменить название поля. А в API можно.

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

  • Перестановка мест слагаемых в json

  • Перестановка мест слагаемых в form-data

  • Регистрозависимость

  • Другой тип метода

  • Well formed json / xml

Ну а если что-то подзабудется, то можно открыть эту статью и свериться с чек-листом отсюда! =))

PS — больше полезных статей ищите в моем блоге по метке «полезное». А полезные видео — на моем youtube-канале  

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

Примеры:

  • умножить на калькуляторе цифр 3 и 5,
  • в игре посадить морковь на грядку для овощей,
  • оплатить покупку действующей картой.

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

Пример:

  • умножить на калькуляторе числа 3 на грушу (значение «груша» не является валидным для калькулятора),
  • в игре посадить морковь на реку,
  • оплатить покупку несуществующей картой.

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

Реакция продукта на тесты

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

Позитивное тестирование должно нам всегда давать результат в виде отсутствия багов.

Негативные проверки могут дать 2 результата:
1. На данный ввод у продукта есть ответ в виде сообщения/контроля.
2. Система не знает, как реагировать на введенные данные.

Получается, есть три реакции на действия по вводу данных:
— Действие: создание сущности, переход на новый шаг и т.п.
— Контроль: сообщение с контролем, блокировка дальнейших действий и т.п.
— Отказ: возникает исключение Exception, 404-ой ошибки и т.п.

Для чего важно различать?

Для чего нам различать негативное и позитивное тестирование? Чтобы верно расставлять приоритеты в тестировании в зависимости от ситуации.

Создание позитивных сценариев (тест-кейсов), как правило, предшествует созданию негативных.

Сначала мы проверяем работу системы, когда наш условный пользователь работает с системой «правильно». А уже потом приступаем к проверке отклика системы на пользователя, который допускает различные ошибки (ввод неверных данных, например). И наша система должна быть готова ответить на неверный запрос. Это и есть цель негативного тестирования.

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

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

Пример позитивных и негативных тестов

Давайте рассмотрим эти виды тестирования немного подробнее на примере формы авторизации на сайте.

Авторизация на сайте
Авторизация на сайте

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

  • Авторизация с правильным логином и паролем

К негативным тестам можно отнести следующие сценарии:

  • Авторизация с неправильным логином
  • Авторизация с неправильным паролем
  • Авторизация с неправильным логином и паролем
  • Авторизация с пустым логином
  • Авторизация с пустым паролем
  • Авторизация с пустым логином и паролем

***

Повторюсь, при тестировании очень важно соблюдать приоритет.

________________________________

Сначала мы выполняем позитивные тесты, а потом негативные.

________________________________

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

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

Improve Article

Save Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Every software development process follows Software Development Life Cycle(SDLC) finally to develop a quality software product. In which Software testing is one of the important phase as it only ensures the quality of the product. So, for that different types of software testing are performed to check different parameters or test cases.

    In this article we will discuss about Negative testing and will know about it like what is this testing actually, how it is performed , why it is performed and finally advantages and disadvantages of performing this testing. So, let’s start exploring the topic. 

    Negative Testing :
    Negative Testing is performed to ensure that the software application or the product does not fail or behave abnormally whenever a user gives any unintentional or unexpected input to the software application. Means the main motto of doing negative testing is to check how the software behaves when some unexpected input is given to the software. When this testing is performed to break the system and verify the response of application during unwanted inputs.

    Negative Test Cases :
    Some components of Negative testing are called Negative test cases. The team creates it to test the application. The team uses following testing efforts:

    • Data Bound Test –
      Here the team tests all the upper and lower bounds of data fields.
    • Field Size Test –
      It prevents users from facing more characters before getting error message that they have crossed the limit.
    • Necessary Data Test –
      The test ensures that it every data on screen is verified before critical data is entered.
    • Numeric Bound Test –
      This test ensures that test cases of negative test are accurate where the team analyzes both lower and upper bounds.
    • Implanted Quote –
      Software systems face some issues when end-users store information with single quote. So for all the screens, the team should provide more than one single quotes.
    • Modification in Performance –
      This test contains test cases which compares previous and current release performance statistics which can help to identify potential performance problems.
    • Web Session Testing –
      Here the testing builds test cases to release web pages within the application only which doesn’t involve user log in.

    How to perform Negative Testing ?

    • Initially it is important to think about the possible scenarios that could affect your application negatively.
    • While exploring scenarios we need to prioritize some testing parameters where it is ensured there is no wastage of time or money.
    • Now we build a test case which includes testing of data input where the application may be crashed. That is exactly what we don’t want to happen when a client uses the product.
    • The security pitfalls should be eradicated while forming priorities of test case.
    • It is very helpful to think about the unwanted and unexpected data that could enter our program which includes simple mistakes which gives frustration to users.

    Benefits of Negative Testing :
    Some of the significant benefits in Negative testing are:

    1. It gives more benefit to client before going live.
    2. It covers all bases and enhances the possibility by covering each type of error.
    3. Implementation of negative testing ensures a product to be of good quality with zero or negligible vulnerabilities.
    4. To ensure all test cases are covered, one round of negative test is performed before positive testing.

    Real-world example of Negative Testing :
    Let’s assume that there are two boxes in login screen of an application one is “username” and other is “password” which has following requirements to be valid:

    • Username can’t be blank, will have characters only.
    • Username can contain maximum 10 characters.
    • Password can contain only combination of alpha-numeric values and further no other type of character is allowed.
    • Password must contain maximum 10 characters.
    • Some of the positive test scenarios can include:
    • Username: Satyabrata  Password: qwerty123
    • Verify if user login with valid credentials
    • Some of the negative test scenarios can include:
    • Username: 9876=)  Password: /*-+
    • Then verify username and password.  The purpose to enter such content is to check how the application responds to unexpected input and hence ensures quality assurance.

    Disadvantages of Negative Testing :
    For enhancement of application Negative testing is helpful but has certain drawbacks:

    1. The execution of it requires investment of time, money and effort.
    2. Customers have to extreme delays as they have to wait till the product released.
    3. In some cases there is no need to execute excessive negative testing.
    4. There has to be a trained  and professional engineer in order to implement Negative testing.

    Finally, Negative testing ensures that the product or application delivered to customer has no bugs. To build effective negative testing scenario we require creative and intelligent test engineers. Each software company aims to be capable to undertake negative testing. So by implementing Negative testing we can improve the quality of software.

    Improve Article

    Save Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Every software development process follows Software Development Life Cycle(SDLC) finally to develop a quality software product. In which Software testing is one of the important phase as it only ensures the quality of the product. So, for that different types of software testing are performed to check different parameters or test cases.

    In this article we will discuss about Negative testing and will know about it like what is this testing actually, how it is performed , why it is performed and finally advantages and disadvantages of performing this testing. So, let’s start exploring the topic. 

    Negative Testing :
    Negative Testing is performed to ensure that the software application or the product does not fail or behave abnormally whenever a user gives any unintentional or unexpected input to the software application. Means the main motto of doing negative testing is to check how the software behaves when some unexpected input is given to the software. When this testing is performed to break the system and verify the response of application during unwanted inputs.

    Negative Test Cases :
    Some components of Negative testing are called Negative test cases. The team creates it to test the application. The team uses following testing efforts:

    • Data Bound Test –
      Here the team tests all the upper and lower bounds of data fields.
    • Field Size Test –
      It prevents users from facing more characters before getting error message that they have crossed the limit.
    • Necessary Data Test –
      The test ensures that it every data on screen is verified before critical data is entered.
    • Numeric Bound Test –
      This test ensures that test cases of negative test are accurate where the team analyzes both lower and upper bounds.
    • Implanted Quote –
      Software systems face some issues when end-users store information with single quote. So for all the screens, the team should provide more than one single quotes.
    • Modification in Performance –
      This test contains test cases which compares previous and current release performance statistics which can help to identify potential performance problems.
    • Web Session Testing –
      Here the testing builds test cases to release web pages within the application only which doesn’t involve user log in.

    How to perform Negative Testing ?

    • Initially it is important to think about the possible scenarios that could affect your application negatively.
    • While exploring scenarios we need to prioritize some testing parameters where it is ensured there is no wastage of time or money.
    • Now we build a test case which includes testing of data input where the application may be crashed. That is exactly what we don’t want to happen when a client uses the product.
    • The security pitfalls should be eradicated while forming priorities of test case.
    • It is very helpful to think about the unwanted and unexpected data that could enter our program which includes simple mistakes which gives frustration to users.

    Benefits of Negative Testing :
    Some of the significant benefits in Negative testing are:

    1. It gives more benefit to client before going live.
    2. It covers all bases and enhances the possibility by covering each type of error.
    3. Implementation of negative testing ensures a product to be of good quality with zero or negligible vulnerabilities.
    4. To ensure all test cases are covered, one round of negative test is performed before positive testing.

    Real-world example of Negative Testing :
    Let’s assume that there are two boxes in login screen of an application one is “username” and other is “password” which has following requirements to be valid:

    • Username can’t be blank, will have characters only.
    • Username can contain maximum 10 characters.
    • Password can contain only combination of alpha-numeric values and further no other type of character is allowed.
    • Password must contain maximum 10 characters.
    • Some of the positive test scenarios can include:
    • Username: Satyabrata  Password: qwerty123
    • Verify if user login with valid credentials
    • Some of the negative test scenarios can include:
    • Username: 9876=)  Password: /*-+
    • Then verify username and password.  The purpose to enter such content is to check how the application responds to unexpected input and hence ensures quality assurance.

    Disadvantages of Negative Testing :
    For enhancement of application Negative testing is helpful but has certain drawbacks:

    1. The execution of it requires investment of time, money and effort.
    2. Customers have to extreme delays as they have to wait till the product released.
    3. In some cases there is no need to execute excessive negative testing.
    4. There has to be a trained  and professional engineer in order to implement Negative testing.

    Finally, Negative testing ensures that the product or application delivered to customer has no bugs. To build effective negative testing scenario we require creative and intelligent test engineers. Each software company aims to be capable to undertake negative testing. So by implementing Negative testing we can improve the quality of software.

    Если вдруг вам лень читать, то у нас есть еще и видео на эту тему 🙂 https://youtu.be/JOCqwgRO_JQ

    Представьте, что перед вами стоит задача проверки поля в форме. С чего начнете? Наверняка найдутся те, кто бросится ломать форму и вводить некорректные данные. Но большинство упомянет о необходимости проведения сначала позитивных проверок, ведь прежде необходимо убедиться, что поле в принципе способно обрабатываться. И уже потом вы перейдете к негативным. И будете правы. Но только в теории. 🙂

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

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

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

    Общепринятое определение звучит так:

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

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

    С позитивными кейсами ответ однозначный: ввели «хорошие» данные — получили результат “success”. А если вводим «плохие»? Здесь мы столкнулись с некоторой неоднозначностью. У негативных проверок может быть два результата:

    1. на данный ввод у системы есть ответ в виде сообщения/контроля;
    2. система не знает, как реагировать на введенные данные.

    То есть у системы есть как минимум три реакции на наши действия по вводу данных:

    1. Действие: создание сущности, переход на новый шаг и т.п.
    2. Контроль: сообщение с контролем, блокировка дальнейших действий и т.п.
    3. Отказ: возникает исключение Exception, 404-ой ошибки и т.п.

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

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

    Для себя я ввела некий условный «Жизненный цикл ПО в негативе». Его идея в том, что количество и тип негативных проверок будет зависеть от того, в какой стадии находится проект.

    I этап.
    NEWBORN
    Проект пока еще как младенец. ЦА вроде бы изучена, аналитики написали первые варианты Технических Заданий (ТЗ), разработчики уже сделали первый вариант продукта и позвали нас тестировать.

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

    II этап.
    TEENAGER

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

    III этап.
    ADULT

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

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

    Конечно, на деле все не так просто, именно поэтому в начале статьи я сказала о том, что универсального правила когда, сколько и где проводить негативное тестирование — нет. Как нет однозначного ответа на вопрос, где заканчивается позитивное и начинается негативное тестирование, и что вообще понимать под этим процессом.

    Например, куда отнести следующий кейс (все совпадения случайны и, наверняка, он был учтен “Амазоном”, но давайте пофантазируем): покупатель зашел в магазин Amazon Go за покупками, съел сэндвич на месте, вернул коробочку из-под него на место и вышел с пустыми руками, без оплаты покупки. С точки зрения линейного процесса и реализованного кода все отработало идеально. С точки зрения бизнес-процесса — это явный fail. Задумались? Куда бы вы отнесли данный кейс? Может, у вас есть свои примеры, доказывающие, что в этом мире нет ничего однозначно черного или белого? Поделитесь в комментариях 😉

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

    1. Функцию вычисления корня в калькуляторе.
    2. Работу с корзиной (добавление / удаление / редактирование) в интернет-магазине.

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

    Поэтому я решила написать поясняющую статью.

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

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

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

    Не работает основной сценарий, зачем дальше вообще что-то проверять? Так магазин и теряет пользователей.

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

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

    Посмотрим на примере:

    1. Функция вычисления корня в калькуляторе.

    Основной тест-кейс — проверить, что корень из корректного числа действительно вычисляется.

    Разбить можно на следующие классы эквивалентности:

    • После вычисления корня остается целое число (корень из 4 = 2)
    • После вычисления корня остается дробное число (корень из 3)

    Хм, а что, если дробное число у нас будет не только после вычисления корня, но и до? Можем же мы взять корень из числа 2,2 ? Позитивный тест? Позитивный!

    Также можно разделить числа на небольшие, до 100, например. Потом взять интервал от 100 до размера int и третий будет еще больше, сколько влезает в наш калькулятор. 3 класса эквивалентности, проверяем по одному значению из интервала.

    Не забудем и про граничные значения, проверим 0. Позитивный тест? А как же! Корень из 0 равен 0, а не ошибке!

    Из основного, пожалуй, все.

    2. Работа с корзиной в интернет-магазине.

    О, вот где простор для воображения!

    Пользователь столько разных сценариев может выполнить!! Но в первую очередь возьмем основные, самые короткие. Потому что если уж они не работают, то длинные цепочки (добавил — отредактировал — удалил — снова добавил — итд) проверять точно не стоит. Итак:

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

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

    Думаете, будет работать, если работает по отдельности? Не-е-е-ет, ребята, вы же тестировщики! Никогда не верьте программам «на слово»! Придумали сценарий? Проверьте!

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

    А сам сценарий позитивный? Да! Хотя уже и с нотками извращения, надо признать Smile :)

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

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

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

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

    Но, как бы не был такой сайт удобен, если он не в состоянии отработать при влиянии человеческого фактора, пользователь рано или поздно уйдет. «Шаг влево, шаг вправо — расстрел», кому это понравится? Хочется иметь возможность ошибаться и исправлять ошибки, а не получать «по рукам» страшными сообщениями об ошибке на весь экран.

    Поэтому мы проводим негативное тестирование. Что такое негативное тестирование? Это ввод заведомо некорректных данных. Вводим и смотрим, как ведет себя программа, понятные ли сообщения об ошибке выдает…

    Но как составлять такие тесты? Посмотрим на примерах:

    1. Функция вычисления корня в калькуляторе.

    Первое, что приходит на ум — а что будет, если вычислить корень из отрицательного числа? 

    Но что еще тут можно придумать?

    • Корень из пустоты — вспоминаем о граничных значениях, мы не можем ввести строку отрицательной длины, но вот граничное значение (строка нулевой длины) можем!
    • Корень из символов — надо проверить, что скажет система, если ввести или вкопипастить туда что-то символьное. Причем символы мы делим на русские, английские и спецсимволы!
    • Корень из значения «четыре» — также символы можно поделить на абракадабру и «типа число». Кстати, если уж говорить о таких «типа числах»…
    • Попробуем ввести строку, которая обозначает число. И взять корень уже из нее.

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

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

    2. Работа с корзиной в интернет-магазине.

    Тут, опять же, можно найти числовое поле и поиграться с ним, как мы это только что проделали с калькулятором. Поле «количество товара» тут очень подойдет! Но, с другой стороны, скучно же, такие разные приложения и одни и те же тесты?

    Кстати, не хочу сказать, что их не надо проводить. Надо, еще как надо! Просто я в статье повторяться уже не буду. Хочется здесь упомянуть о важной особенности всяких web-приложений и главном негативном тесте, который обычно все и ломает.

    Запомните всего 2 слова — разные вкладки!

    Чувствуете? Давайте поясню. Негативный тест на удаление товара из корзины — попытаться удалить уже удаленный товар. И тут начинаются варианты, как это может быть сделано:

    • Открыли корзину в 2 вкладках браузера. Сначала нажали «удалить» в одной, потом во второй. То есть попытка удалить то, что ты сам уже удалил из своей же корзины.
    • Попытка удалить удаленный админом товар. В 1 вкладке под админом удаляем товар вообще, в принципе, а в другой пытаемся его под пользователем удалить из корзины.

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

    А что будет, если админ не передвинул товар в иерархии магазина (в другую категорию переместил, исходно неверно был размещен товар), а просто поправил, отредактировал описание? Тоже ничего сломаться не должно!

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

    Например, мы можем создавать карточку — человека, здания, той же книги, чего-то еще… Попробуйте ее отредактировать в 2 окна. В одном изменить одно поле, сохранить, а потом во втором изменить другое поле и тоже сохранить. Или что-то удалить, а во втором окне добавить или изменить. 

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

    Хочется привести еще один пример из реальной практики. Тоже web-интерфейс, в котором можно нажать «создать» и добавить новую карточку. Пользователь добавляет, а у него через раз формочка падает. Почему?

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

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

    Так что, ребята, дерзайте! Открывайте разные вкладки и вперед, ищите информацию о том, как же, ну как же ведет себя именно ваша программа при противоречивых воздействиях на нее? Wink ;)

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

    Заходите к нам на огонек! ツ

    Понравилась статья? Поделить с друзьями:
  • Что такое небывалый праздник
  • Что такое не удается найти файл сценария c windows run vbs
  • Что такое молдавский сценарий
  • Что такое национальный праздник россии
  • Что такое модель сценариев процесса