Позитивное и негативное тестирование. Позитивное мышление в мире негативного тестирования Позитивное и негативное тестирование

Позитивное и негативное тестирование. Позитивное мышление в мире негативного тестирования Позитивное и негативное тестирование
Позитивное и негативное тестирование. Позитивное мышление в мире негативного тестирования Позитивное и негативное тестирование

Вольный перевод статьи "Top 10 Negative Test Cases" Steve Miller.

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

Внутренние одинарные кавычки (Embedded Single Quote) - У большинства SQL баз данных возникают проблемы при наличии одинарных кавычек в запросе (например, Jones’s car).
Используйте одинарные кавычки при проверке каждого поля ввода работающего с базой данных.

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

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

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

Числовые граничные значения (Numeric Bounds Test) - Числовые поля вашего приложения могут иметь ограничения допустимых числовых значений. Эти ограничения могут быть указаны в спецификации вашего приложения либо вытекать из логики работы программы (например, если вы тестируете функциональность связанную с начислением процентов на счет, то вполне логичным будет предположение, что начисленные проценты не могут принимать отрицательное значение).
Проверяйте, что приложение выдает сообщение об ошибке в случае, если значения лежат за пределами допустимого диапазона (например, сообщение об ошибке должно появляться при вводе значений 9 или 51 в поле с допустимым диапазоном значений от 10 до 50, либо при вводе отрицательного значения в поле, значения которого должны быть положительными).

Числовые ограничения (Numeric Limits Test) - Большинство баз данных и языков программирования определяют числовые значения как переменные с некоторым типом (например, integer или long integer), которые, в свою очередь, имеют ограничения допустимых числовых значений (например, значения integer должны находиться в диапазоне от -32768 до 32767, а long integer от -2147483648 до 2147483647).
Проверяйте граничные значения используемых переменных, для числовых полей, граничные значения которых четко не определены спецификацией.

Граничные значения даты (Date Bounds Test) - Очень часто в приложениях существуют логические ограничения для полей содержащих дату и время. Например, если вы проверяете поле содержащее дату рождения пользователя, то вполне логичным будет запрет ввода еще не наступившей даты (т.е. даты в будущем), либо ограничение на ввод даты отличающейся от сегодняшней более, чем на 150 лет.

Валидность даты (Date Validity) - Поля даты всегда должны иметь проверку валидности введенных значений (например, 31-11-2009 - не валидная дата). Также, не забывайте и о проверке дат в високосном году (годы кратные 4м и кратные 100 и 400 одновременно - високосные).

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

Мы (не такой уж это и секрет) очень переживаем за качество своих продуктов и с трепетом наблюдаем за обваливанием системы. Это оправдывает существование тестировщиков в мире. Это заставляет нас чувствовать себя героями: пришёл великий Тестер и спас своих пользователей от ужасных критических багов!

И наши тестировщики никогда не забывают про негативное тестирование, хотя не всех прогеров это радует. Но такие проверки не прихоть «злых тестеров», они вызваны необходимостью закрыть уязвимости и обезопаситься от проникновения в систему хакеров и ботов, Dos/DDos атак.

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

Понимаете, программисты-то пишут софт, нацеливаясь на результат, на запланированный релиз, летят на крыльях вдохновения! А тут наступает этап проверки и многочисленных исправлений и правок «идеального» кода. И всё, прячься кто куда, система на тестировании.

Чтобы никого не нервировать, некоторые специалисты могут откладывать негативное тестирование на потом или вообще игнорировать его (ужас!) в угоду сокращения сроков и бюджета. Ну а чего проверять, если прога не делает даже того, что должна, правда? Не-а.

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

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

Позитивное тестирование - это проверка работы системы на соответствие её нормальному (штатному, ожидаемому) поведению, согласно ТЗ и . То есть здесь мы смотрим, делает ли ПО то, чего от него ждут, соответствует ли реализация современным требованиям, поддержаны ли гайдлайны пользовательского интерфейса и т.д.

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

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

Поэтому, по нашему мнению,

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

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

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

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

Проверяет всё по ТЗ и тестовым сценариям, смотрит, как данные обрабатываются, которые юзер должен ввести в поля (не факт, что введёт, кстати) и тут вот оно – озарение! Ему кажется, что если ввести вот в это поле для login какой-нибудь «%адынадын/>», а не обычный текст, то что-то точно произойдёт. Что-то тёмное и мрачное неправильное.

И что? Он должен сказать себе: «Нет. Сейчас я должен заниматься позитивным тестированием и ничем другим. Вот у меня назначено негативное на следующей неделе, тогда и настанет время для %адынадын/>. Наверное»?

Мы считаем такой подход к негативному тестированию неэффективным, и вот почему:

  1. Если проводить позитивное и негативное тестирование по отдельности, то это будет дольше. Как минимум потому, что это будут уже две итерации тестирования.
  2. Тестеры и кодеры живут в условиях дедлайнов. И если время строго ограничено, то откладывание негативного тестирования на потом повышает риск того, что про него вообще в итоге забудут. Ведь чем ближе к моменту Х, тем быстрее летит время, скорее требуется выполнить поставленные задачи, исправить дефекты, применить финальные бизнес требования (которые могут измениться) и доделать ещё кучу дел. Дедлайн – время горячее!
  3. Разделение негативного и позитивного тестирования, по нашему мнению, просто противоречит природе тестера! Ведь основная его задача – это проверка системы на все возможные действия конечного юзера. А люди в большинстве своём нелогичны, и могут делать с софтом самые разные непотребства;)

Мы, как тестировщики, очень переживаем, если система содержит ошибки по проверкам из категории негативных. И особенно, если последствия таких ошибок критичны для всей системы. Но репортить их не боимся. Особенно с таким козырем в рукаве – у нас в команде есть девочки-тестировщицы. И кто сможет упорно отстаивать «идеальность» кода, когда они нежными голосками в пух и прах разносят работоспособность проекта? То-то же.

Так какие выводы мы можем сделать?

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

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

· Дымовое тестирование. На этой стадии необходимо проверитьработает ли система вообще (правильно ли работает, правильно лиобрабатывает ошибки и пр.). Это делается для того, чтобы понятьпригодно ли приложение для дальнейшего тестирования или оноизначально работает неправильно.

· «Позитивное» тестирование». На этой стадии необходимо проверить результат работы приложения при получении им «правильных» входных данных.

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

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

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

1) проверьте, как работает приложение, когда оно получает навход корректные данные;

2) если все работает правильно, как описано в спецификацииследующим шагом является проверка граничных значений (минимальные и максимальные значения корректных данных);

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

В первых двух пунктах описан процесс, который называется «позитивным» тестированием.

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

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

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


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

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

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

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

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

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

Вопросы к теме 18

При тестировании программного продукта применяется огромное количество различных видов тестов. Наиболее широкую и подробную классификацию предложил автор книги «Тестирование Дот Ком» Роман Савин. Он объединил виды тестирования по таким признакам, как объект, субъект тестирования, уровень, позитивность тестирования, и степень автоматизации тестирования. Классификация была дополнена на основании таких источников, как книга Сэма Канера, «Тестирование программного обеспечения» и интернет-ресурс, посвященный тестированию, «Про Тестинг - Тестирование Программного Обеспечения».

По объекту тестирования

  • · Функциональное тестирование. Функциональное тестирование на сегодняшний день является одним из наиболее часто применяемых видов тестирования. Задача такого тестирования - это установить на сколько соответствует разработанное программное обеспечение (ПО) требованиям заказчика с точки зрения функционала. Иначе говоря, проведение функциональных тестов позволяет проверить способность информационной системы решать задачи пользователей.
  • · Нефункциональное тестирование. Позволяет проверить соответствие свойств программного обеспечения с поставленными нефункциональными требованиями. Таким образом, нефункциональное тестирование - это тестирование всех свойств программы, не относящихся к функциональности системы. Такими свойствами могут быть предъявленные характеристики с точки зрения таких параметров как:
  • - Надежность (способность системы реагировать на непредвиденные ситуации).
  • - Производительность (способность системы работать под большими нагрузками).
  • - Удобство (исследование удобства работы пользователя с приложением).
  • - Масштабируемость (возможность масштабировать приложение как вертикально, так и горизонтально).
  • - Безопасность (исследование возможности нарушения работы приложения и кражи пользовательских данных злоумышленниками).
  • - Портируемость (возможность перенести приложение на определенный набор платформ)

И много других качеств.

  • · Тестирование пользовательского интерфейса. Это тестирование корректности отображения элементов пользовательского интерфейса на различных устройствах, правильности реагирования их на совершение пользователем различных действий насколько и оценка того, насколько ожидаемо ведет себя программа в целом. Такое тестирование дает возможность оценить, насколько эффективно пользователь сможет работать с приложением и насколько внешний вид приложения соответствует утвержденным документам, созданными дизайнерами. При проведении тестирования пользовательского интерфейса основной задачей тестировщика является выявление визуальных и структурных недостатков в графическом интерфейсе приложения, проверке возможности и удобства навигации в приложении и корректность обработки приложением ввода данных с клавиатуры, мыши и других устройств ввода. Тестирование пользовательского интерфейса необходимо для того, чтобы убедиться в том, что интерфейс соответствует утвержденным требованиям и стандартам, и гарантировать возможность работы пользователя с графическим интерфейсом приложения.
  • · Тестирование удобства использования. Это способ тестирования, позволяющий оценить степень удобства использования приложения, скорость обучения пользователей при работе с программой, а также насколько пользователи разрабатываемого продукта находят ее понятной и привлекательной в контексте заданных условий. Такое тестирование необходимо для обеспечения максимально положительного пользовательского опыта при работе с приложением.
  • · Тестирование защищенности. Позволяет выявить главные уязвимости программного обеспечения по отношению к различным атакам со стороны злоумышленников. Компьютерные системы довольно часто подвергаются кибер атакам с целью нарушения работоспособности информационной системы либо кражи конфиденциальных данных. Тестирование безопасности дает возможность проанализировать реальную реакцию и действенность защитных механизмов, использованных в системе, при попытке проникновения. В процессе тестирования безопасности тестировщик пытается выполнять те же действия, которые выполнял бы настоящий взломщик. При попытке тестировщиком взломать систему могут использоваться любые средства: атаки системы при помощи специальных утилит; попытки узнать логины и пароли с помощью внешних средств; DDOS атаки; целенаправленная генерация ошибок для обнаружения возможности проникновения в систему в процессе её восстановления; использование известных незакрытых уязвимостей системы.
  • · Инсталляционное тестирование. Под этим термином подразумевают тестирование корректности установки (инсталляции) определенного программного продукта. Такое тестирование обычно происходит в искусственно созданных средах с целью выявить степень готовности программного обеспечения к эксплуатации. Основные причины проведения таких тестов связаны с необходимостью проверить корректность поведения программного продукта при автоматизированном развертывании либо обновлении. Обеспечение правильной и стабильной установки программного обеспечения является очень важным фактором при создании программного продукта, поскольку позволяет пользователям быстрее и с меньшими усилиями начать использовать продукт, при этом обеспечивая одинаково корректное поведение этого продукта во всех протестированных программных средах.
  • · Конфигурационное тестирование. Конфигурационное тестирование предназначено для оценки работоспособности программного обеспечения при разнообразных конфигурациях системы. В зависимости от типа тестируемого программного продукта, конфигурационное тестирование может преследовать разные цели. Обычно это либо определение оптимальной конфигурации оборудования, обеспечивающего достаточные для работы ПО параметры производительности, либо проверка определенной конфигурации оборудования (или платформы, включающей в себя помимо оборудования, стороннее ПО, необходимое для работы программы) на совместимость с тестируемым продуктом. Если речь идет о клиент-серверном программном обеспечении, то конфигурационное тестирование проводится отдельно для сервера и отдельно для клиента. Обычно при тестировании совместимости сервера с определенной конфигурацией стоит задача найти оптимальную конфигурацию, поскольку важна стабильность работы и производительность сервера. В то время как при тестировании клиента, наоборот, пытаются выявить недостатки ПО при любых конфигурациях и по возможности устранить их.
  • · Тестирование надежности и восстановления после сбоев (стрессовое тестирование). Такой вид тестирования довольно часто проводится для программного обеспечения, работающего с ценными пользовательскими данными, бесперебойность работы и скорость восстановления после сбоев которого критичны для пользователя. Тестирование на отказ и восстановление осуществляет проверку способности программы быстро и успешно восстанавливаться после отказа оборудования, перебоев сети или критических ошибок в самом программном обеспечении. Это дает возможность оценить возможные последствия отказа и время, необходимое для последующего восстановления системы. На основе полученных в ходе тестирования данных может быть оценена надежность системы в целом, и, при условии неудовлетворительных показателей, соответствующие меры, направленные на улучшение систем восстановления, могут быть приняты
  • · Тестирование локализации. Тестирование локализации дает возможность выяснить насколько хорошо приспособлен продукт для населения определенных стран и насколько он соответствует ее культурным особенностям. Обычно, рассматриваются культурный и языковой нюансы, а именно перевод пользовательского интерфейса, сопутствующей документации и файлов на определенный язык, также тестируется правильность форматов валют, чисел, времени и телефонных номеров.
  • · Нагрузочное тестирование. Нагрузочное тестирование позволяет выявить максимальное количество однотипных задач, которые программа может выполнять параллельно. Самая популярная цель нагрузочного тестирования в контексте клиент-серверных приложений - это оценить максимальное количество пользователей, которые смогут одновременно пользоваться услугами приложения.
  • · Тестирование стабильности. Тестирование стабильности проверяет работоспособность приложения при длительном использовании на средних нагрузках. В зависимости от типа приложения, формируются определенные требования к длительности его бесперебойной работы. Тестирование стабильности стремится выявить такие недочеты приложения как утечки памяти, наличие ярко выраженных скачков нагрузки и прочие факторы, способные помешать работе приложения в течение длительного периода времени.
  • · Объемное тестирование. Задачей объемного тестирования поставлено выявление реакции приложения и оценка возможных ухудшений в работе ПО при значительном увеличении количества данных в базе данных приложения. Обычно в такое тестирование входит:
  • - Замер времени выполнения операций, связанных с получением или изменением данных БД при определенной интенсивности запросов.
  • - Выявление зависимости увеличения времени операций от объема данных в БД.
  • - Определение максимального количества пользователей, которые имеют возможность одновременно работать с приложением без заметных задержек со стороны БД.
  • Тестирование масштабируемости. Это вид тестирования программного обеспечения, предназначенный для проверки способности продукта к увеличению (иногда к уменьшению) масштабов определенных нефункциональных возможностей. Некоторые виды приложений должны легко масштабироваться и, при этом, разумеется, оставаться работоспособными и выдерживать определенную пользовательскую нагрузку .

Тестирование, связанное с изменениями

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

По уровню тестирования

  • · Модульное тестирование (Unit тесты). Заключается в проверке каждого отдельного модуля (самобытного элемента системы) путем запуска автоматизированных тестов в искусственной среде. Реализации таких тестов часто используют различные заглушки и драйверы для имитации работы реальной системы. Модульное автоматизированное тестирование - это самая первая возможность запустить и проверить исходный код. Создание Unit тестов для всех модулей системы позволяет очень быстро выявлять ошибки в коде, которые могут появиться в ходе разработки.
  • · Интеграционное тестирование. Это тестирование отдельных модулей системы на предмет корректного взаимодействия. Основная цель интеграционного тестирования - найти дефекты и выявить некорректное поведение, связанное с ошибками в интерпретации или реализации взаимодействия между модулями.
  • · Системное тестирование. Это тестирование программы в целом, такое тестирование проверяет соответствие программы заявленным требованиям.
  • · Приемочное тестирование. Это комплексное тестирование, определяющее фактический уровень готовности системы к эксплуатации конечными пользователями. Тестирование проводится на основании набора тестовых сценариев, покрывающих основные бизнес-операции системы .

По исполнению кода

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

По субъекту тестирования

  • · Альфа-тестирование. Это тестирование проводится для самых ранних версий компьютерного программного обеспечения (или аппаратного устройства). Альфа-тестирование почти всегда проводится самими разработчиками ПО. В процессе альфа-тестирования разработчики приложения находят и исправляют ошибки и проблемы, имеющиеся в программе. Обычно, во время Альфа-тестирования происходит имитация работы с программой штатными разработчиками, реже имеет место реальная работа как потенциальных пользователей, так и заказчиков с продуктом. Как правило, альфа-тестирование проводится на самом раннем этапе разработки ПО, однако в отдельных случаях может быть применено для законченного или близкого к завершению продукта, например, в качестве приёмочного тестирования.
  • · Бета-тестирование. Тестирование продукта, по-прежнему находящегося в стадии разработки. При бета-тестировании этот продукт предоставляется для некоторого количества пользователей, для того чтобы изучить и сообщить о возникающих проблемах, с которыми сталкиваются пользователи. Такое тестирование необходимо чтобы найти ошибки, которые разработчики могли пропустить. Обычно бета-тестирование проводится в две фазы: закрытый бета-тест и открытое бета-тестирование. Закрытый бета-тест - это тестирование на строго ограниченном кругу избранных пользователей. Такими пользователями могут выступать знакомые разработчиков, либо их коллеги, не связанные напрямую с разработкой тестируемого продукта. Открытое бета-тестирование заключается в создании и размещении в открытом доступе публичной бета-версии. В данном случае любой пользователь может выступать бета-тестером. Обратная связь от таких бета-тестеров осуществляется с помощью отзывов на сайте и встроенных в программу систем аналитики и логирования пользовательских действий, эти системы необходимы для анализа поведения пользователей и обнаружения трудностей и ошибок, с которыми они сталкиваются .

По позитивности сценария

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

По степени автоматизации

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

Ииииииии... Это последняя запись из цикла! Она самая короткая, самая простая и практически целиком состоит из реальных историй. По возможности — глупо-смешных. Даже есть видео, снятое специально для записи вот прямо в момент написания. Свежачок-с. К сожалению, я не догадался снять скриншот с сообщением о падении Youtube клиента, он бы подошёл. Упал прямо при заливке того ролика, который вставлен в статью. Ладно, пусть будет мой экран блокировки.

На старте тестирования, вне зависимости от того, новый это проект или такой, что его стоило бы уже похоронить, в целом всегда ясно, с чего начинать. Если, конечно, к момент старта тестирования ни одно из звеньев цепи не слажало. Обычно тестировщики вычитывают требования и прочие документы с нерусскими названиями, типа «БиЭрКью», «ЭсАрки» и «Юзер стори» и прикидывают, как написать тест кейс, чтобы он проверил выполенения всех этих документов. Это всё понятно, на поверхности и нет смысла на этом задерживаться. Но есть ещё поведение самого Android, о котором иногда не знают не то что аналитики, но даже архитекторы и некоторые разработчики. А помня, что , только с кастомами, таких особенностей всплывает довольно много. И я говорю не о стрессовых сценариях, когда памяти нет или батарейку внезапно вынули (как-то встречал негодование человека на терминал GNU/Linux, что тот не показывает пароль при вводе, а у него глючная клавиатура и он не понимает, вводит пароль или же это клавиатура снова не работает), а о штатном поведении кастомизации Android и даже поведении, заложенном в AOSP. То есть штатные поведения системы, которые могут отрицательно сказаться на тестируемом продукте. Так называемые, негативные сценарии.


Я кратко опишу некоторые негативные сценарии и попытаюсь дать конкретные примеры.

  • Проблемы связи. Самый просто пример — Fly Mode. К примеру, приложение для заметок Google Keep либо не тестировали в режиме полёта, либо найденные баги не повлияли на релиз. Воспроизвести проблему очень просто:
    • Включаем режим полёта
    • Тапаем на строку Take a note…
    • На появившемся экране выполняем действие Delete
    • Наслаждаемся покадровой анимацией движения сохранённых ранее заметок


Кроме Fly Mode есть и не стабильное подключение с потерей пакетов, и очень медленное подключение, и закрытые порты, через которые работает ваше приложение, и наличие Wi-Fi подключения, но без доступа к Интернету.
  • Нет доступа к магазину приложений . К примеру, чтобы протестировать покупки внутри приложений, нужно, чтобы сборка была выложена в магазин в специальный раздел. Если её там нет, либо там лежит не та же самая версия (речь про version code — внутреннюю версию), то покупки вы не протестируете. Если пользователь улетел в отпуск в Китай, где с подключением к Google Play всё очень печально, у него не должна отваливаться лицензия, за которую он заплатил деньги.
  • Работа приложения при ограничении разрешений , если Target API Level ниже 23, то есть меньше Android 6, и когда версия API 23 и выше. В первом случае приложение является легаси, но разрешения отобрать всё равно можно. Во втором случае оно ещё начнёт получать новые исключения, которых не знавало раньше.
  • Режим экономии заряда батареи . Реализация как Doze и App Standby, так и альтернативные реализации альтернативно одарённых производителей типа Samsung (да и STAMINA от Sony в первой версии), когда всё реализовано ужасно неправильно, но с этим придётся жить. Приложению допустимо не выполнять проверки в срок, не отправлять статистики, не обновлять данные. Но не допустимо падать, зависать, никогда не выполнять запланированные задачи.
  • Изменение даты, времени, часового пояса . Люди могут летать в отпуски и командировки в другие страны, где другой часовой пояс. Если самолёт пересечёт 180-ый меридиан, то пользователь вполне может попасть «во вчера» с точки зрения приложения.

    Реальная история провала. Родительский контроль в KIS для Windows появился в версии 7.0 в 2006 году. В то же время в продукте существовал встроенный новостной агент, вовсе не такой, как сейчас. Предполагалось, что через него будут рассылаться разные новости об угрозах, всякие «что нового» и подобное. В релизной версии, которая уже была установлена у пользователей, был баг. Если перевести время в Windows назад, до начала действия лицензии, то защита отключалась. Строго говоря, не администраторы не могут переводить время, но 10 лет назад в фирмах особо не следили за правами пользователей и там каждый бухгалтер был локальным администратором. Один из наших клиентов в своём маленьком офисе настроил родительский контроль так, чтобы пользователи не могли шариться по Интернету, кроме как в дозволенные сайты. Драконовски настроил и паролем защитил настройки. Всё работало нормально до тех пор, пока во встроенный новостной агент не прислали новость, что пора обновиться на новую версию 7.0.1 где, помимо прочего, исправлена ошибка, из-за которой отключается защита при переводе времени в обратную сторону до начала старта лицензии. Пользователь прочёл новость, обрадовался и вырубил защиту предложенным методом. Через несколько дней эта история от него попала на тогда ещё популярный bash.org.ru. С тех пор новости подобного рода больше не приходили пользователям.

    И не думайте, что подобные ошибки не допускает. Вспомните историю с iOS, которая произошла в этом году, хотя прошло то всего 3 месяца с начала года (Примечание: да, это достаточно старая лекция, я давно хотел её выложить ). Телефоны вырубались, если перевести время ближе к началу исчисления unix time. И как Apple исправил эту ошибку? Они запретили переводить время дальше, чем критичная дата, что НЕ являлось исправлением проблемы. Злоумышленники стали поднимать свои Wi-Fi точки с названиями, которые обычно есть во всяких МакДоналдсах и через них передавать поддельное время. Устройства подключались к таким точкам автоматически и обнаруживали NTP серверы, у которых запрашивали время. Apple банально не позаботилась о том, чтобы iOS не использовала поддельные NTP серверы. Таким образом iOS вновь окирпичивались.

  • Изменение локали системы, языка интерфейса . Пользователь вправе менять язык системы по сто раз на день и никто не может ему этого запретить. Задача тестировщика — убедиться, что продукт во-первых правильно реагирует на это (меняет язык на нужный автоматически), во-вторых вообще не падает. Кроме локали пользователь вправе менять гарнитуры и кегли, подбирая такие, которые ему комфортно читать. Приложение не должно расползаться, если пользователь вносит разумные изменения.
  • Tapjaking . Я упомянал об этой штке в самой первой лекции. Напомню, это перехват тапов, которые принимает активити приложения А, тогда как пользователь пытался добраться до приложения Б. Просто активити приложения А прозрачное. Это выглядит как не безопасное решение Google, но так работают приложения по управлению яркостью и цветовой температурой на устройствах. Пользователям удобны такие приложения и раз Android позволяет им работать без наличия root, это нужно учитывать. К примеру, если у вас приложение, которое для авторизации использует код или, скажем, рисунок, вы обязаны использовать защиту от тапджекинга, например выставить filterTouchesWhenObscured в true.
  • Прямой вызов Activity . Я уже говорил об этом, но повторим. Активити — это одна из точек входа в приложение. Вполне допустимо иметь несколько разных активити, которые могут вызывать внешние приложения, мало ли зачем. Это будут exported активити. Но может быть так, что для вызова некоторого активити нужно ему передать параметры. А стороннее приложение не передаст их. В лучшем случае пользователь увидит какой-то кривой экран, в худшем — ваше приложение упадёт. Так что не стоит, так сказать, светить голой жопой наружу без необходимости. По умолчанию флаг exported выставлен в true и, если вы уверены, что внешние приложения не должны вызывать их, стоит выставить false. Ну а тестировщик должен проверить, как будет вести себя приложение, если вызывать его активити из других приложений.
  • Системный киллер . Вообще он называется OOM Killer — Out Of Memory Killer. Система начинает УБИВАТЬ, если приложению, с которым взаимодействует пользователь в данный конкретный момент, не хватает памяти для работы. Конечно, киллер не тупой, подчиняется опредлённым алгоритмам, выбирая цели (к примеру, система легко убьёт background service, но до последнего будет спасать foreground service; форэгранд сервис это, обычно, тот самы, который рисует свою иконку в области уведомлений, например — плеер), но суть такова. Как правило, на современных устройствах OOM Killer сильно не лютует. Сейчас памяти ставят от одного гигабайта и выше. Но это не касается игр. Игры настолько тяжёлые, так много отжирают памяти, что сколько не отсыпь — всё равно будет мало. И вообще, чем больше оперативной памяти будут засовывать в аппараты, тем жирнее будут приложения, а игры будут самыми жирными. При этом они останутся всё такими же унылыми и ненужными.

    Итог таков, что ваш продукт гарантированно попадёт под ООМ Киллер. Ваша задача состоит в том, чтобы убедиться, что ни к чему плохому это не приводит и продукт поднимется, как только приложение-жиробасина будет схлопнута системой (если это требуется от продукта, конечно). А система сделает это при первой возможности, жить в фоне такой жиробасине она не даст.
    Ещё один вывод — ваше приложение также не должно быть жиробасиной. Любые утечки должны обнаруживаться разработчиком ещё до того, как он напишет реальный код. Ваши тесты производительности обязательно должны иметь сценарии проверки, когда monkey генерирует тонну событий. Если код написан качественно, то сборщик мусора освободит память и система не убьёт процесс приложения. Если всё плохо и приложение течёт из всех щелей, система его пристрелит. Конечно, оно взлетит после этого вновь и память есть уже не будет, потому что после убийства процесса сборщик мусора подчищает всё, но если манки показал, что приложение течёт в его тесте за 15 минут, то у пользователя эти течи хоть и позже, но всё равно проявят себя.

  • Большие данные . Если ваше приложение работает с пользовательскими данными, будьте готовы к тому, что пользователь скормит что-то очень большое безо всякой задней мысли. Например, я, как пользователь, вполне ожидаю, что клиент Youtube загрузит мой ролик, каким бы тяжёлым этот ролик не был. Я ожидаю, что архиватор влезет на любую глубину архива, который весит в 5 раз больше, чем вся доступная оперативная память устройства. Это — нормально. Если кто-то вам говорит, что «никто никогда не будет скармливать такие большие файлы», то, скорее всего, говорящий просто не очень хороший разработчик.
  • Самым глупой и от того смешной ситуацией, вызывающей неправильную работу приложения, вплоть до падения, является простой поворот экрана . Сколько подобных падений было выявлено на этапе тестирования! Особенно если появляется какой-нибудь попап. На попапах опытный тестировщик сразу начинает переворачивать телефон! Бывало и такое, что вся команда тестировала продукт на одних только телефонах, где поворот экрана для приложения был заблокирован. А потом, когда завезли планшетов, оказалось, что на планшетах приложения падает чуть ли не в каждом экране. А потому что фрагменты. На экране и на телефоне были разные интерфейсы и неправильное использование фрагментов приводило к печальному итогу.
  • Двойные, тройные тапы . Почему-то некоторые считают, что никто не делает множественные тапы по элементам интерфейса. Но нет! Я делаю! И не потому что тестирую, а потому что у меня в руках может быть старый телефон на Android 4.0, который и так еле ворочается, так ещё и экран у него не очень отзывчивый. Может быть не понятно, было нажатие или нет и получаются двойные тапы. Не потому что они «дабл» (в смысле не те, которые делаются с интервалом менее секунды), а потому что их получилось два и больше, пока приложение «думало». Например, пока формировало список из множества элементов.
  • Одна из удобных фич Android 6 при недостаточном тестировании приводит к ужасным результатам. Вплоть до того, что её использование явно запрещается в приложении, что, пока, допускается со стороны Google. Эта фича — бэкап и восстановление из бекапа . Она, кстати, не нова, бэкап появился ещё в Android 2.2, но я не знаю ни одного приложения, которое бы использовало эту плюшку.
    Сами по себе создание резервной копии и её восстановление не страшны. Проблемы начинаются, если в продукте используется привязка к идентификатору устройства и идентификатору инсталляции. Даже в пределах одного устройства это может приводить к проблемам, а ведь восстановление из бекапа допускается самим Android на любое устройство с Android 6 на борту: система бекапит приложения с устройства А, а пользователь покупает устройство Б и восстанавливает их все на нём. И работают эти приложения одновременно на двух устройствах, хотя идентификаторы у них разные. Если это клиент-сервереное приложение, где всё общение делается на токенах, здесь возникают куча проблем.

    Боевым примером могу назвать классное приложение Talon for Twitter. Я не делал сброс устройства уже очень давно и потому не знаю, исправил ли автор эту ошибку. Когда я сообщил ему о ней, он мне ответил, почему ошибка возникла (хотя я и так знаю, почему!), но не сказал, будет ли он исправлять поведение. В общем, в этом приложении есть своеобразный мастер установки, который рассказывает о возможностях этого Twitter клиента, по пути запрашивая нужные пермишены. Всё чётко по гайдлайнам Google, прямо по нотам. Когда мастер настройки пройден и нужные пермишены получены, взводился флаг об этом, чтобы повторно не проходить настройку каждый раз. И приложение бэкапилось вместе с этим флагом. Вместе с ним оно и восстанавливалось. Хотя по умолчанию для всех приложений нового типа (т.е. targetApi level >= 23) разрешения отключены. Запускаешь приложение, а оно не может нормально работать. Потому что нет проверки на доступность пермишенов, все проверки остались в мастере первоначальной настройки, который не запускался, потому что флаг был выставлен в значение «мастер уже пройден». Кроме того, после запуска клиент не загружал твиты, давая отлуп от самого Twitter. Потому что прикопанный токен был не валиден на новой инсталляции и нужно было запрашивать новый, а этот запрос также делался в мастере установки на первом же шаге!

  • В Android, начиная с версии (если мне не изменяет память) 2.2.1, появилась возможность штатно перемещать часть данных приложения на карту памяти . Потихоньку эту возможность стали зарезать, пока в Android 6 Google не дал ей вторую жизнь, значительно улучшив. Если производитель устройства в своём кастоме не сломал поведение AOSP в этой ситуации, то, как только Android обнаруживает карту памяти, он предлагает сделать выбор, будет ли пользователь её иногда вытаскивать или нет. Если пользователь говорит, что не планирует её отключать, то Android форматирует карту в свою файловую систему и подключает как часть основной памяти, позволяя устанавливать туда приложения. И здесь несколько подводных камней:
    • Если приложение использует захардкоженные пути, то всё пропало. Но это настолько плохой тон, что, надеюсь, никто так не делает.
    • Если приложение запросило у системы пути при первом запуске и прикопало их навсегда, то будет ровно тоже самое, что и с захардкоженными
  • По мере обновления приложений, пользователи будут получать новые версии из магазина приложений и ставить их поверх существующей. Потому проверка обновления приложения на новую версию — обязательный сценарий. В обычной ситуации всё должно быть нормально, но когда приходится поддерживать множество специфичных устройств своим специфичным поведением, формат настроек может меняться. Почти никогда это не приводит к падениям, если код написан более менее качественно, обрабатывает различные исключения. Но просто потеря части настроек — это уже плохо. К примеру у нас была ситуация, когда пользователи месяцами формировали список антиспама, блокируя номера такси, банков, коллекторских служб, а затем, после обновления на новую версию, все списки терялись. Именно потому что сменился формат настроек и именно здесь, именно в этом месте, настройки не читались новой версией продукта.
  • Кроме обновления продукта на новую версию, бывает более редкий, но гораздо более хардкорный вариант — обновление самой прошивки на новую версию, да при работающем продукте. Я приведу в пример два случая, один из которых уже рассказывал.
    • Обычный Security Update для Android 5.1, который взял и отключил работающие всю жизнь фишки ОС, которым пользовалось приложение
    • После обновления Android 4.4 на Android 5.0, менялись пути установленных приложений. Раньше установленные приложения хранились по одному привычному пути (/data/app/com.package.name.apk). В одном из наших продуктов для внутренних целей, связанных с безопасностью, есть проверка на то, по какому пути защищаемое приложение доступно и не менялся ли он. Прилетело обновление до 5.0 и абсолютные пути изменились для уже установленных приложений (data/app/com.package.name/base.apk). Продукт бил тревогу, что приложение скомпрометировано. Поправили, конечно.
Ну, пока всё. Сейчас я пишу доклад про проблемы, специфичные только для конкретных версий Android, только для конкретных прошивок, только для конкретных устройств. Так что не отключайтесь! Впрочем, часть вы и так знаете — описаны прямо в этой серии записей.
Пока-пока!