Прошлая часть: Что такое баг? Что такое баг-репорт? И для кого на самом деле нужны баги?
Если вы самостоятельно натыкались в интернете на описание видов тестирования ПО – вы примерно знаете как это описание выглядит. Вам показывают картинку из 20-30 видов тестирования, затем предоставляют определения этих 20-30 видов тестирования. Мы же пойдем немного другим путем и немного пофилософствуем, ведь нам же надо перебороть наш мозг в его нежелании запоминать «бесполезные определения», которые ну разумеется «в жизни не пригодятся».
Предлагаю вам задуматься на тему того – почему то, что нас окружает в принципе было изобретено? Например, когда-то раньше люди сталкивались с проблемой того, что продукты быстро портятся при комнатной температуре. Для решения этой проблемы изобрели холодильник. Еще пример – раньше для того, чтобы постирать вещи приходилось тратить много физических усилий – для решения этой проблемы изобрели стиральную машину. А для решения проблемы хаотичного передвижения по дорогам и для обеспечения безопасности движения автомобилей изобрели ПДД. Понимаете, к чему я веду? Практически всё, что человек изобретает – решает какую-либо проблему в его жизни. И как вы могли догадаться – виды тестирования не исключение.
Ну и важное замечание – в данной главе не будут перечислены совершенно все существующие виды тестирования. Будут обозначены лишь те виды тестирования, которые необходимо знать начинающему инженеру тестировщику web-приложений по мнению автора. Глава получилась достаточно большой, поэтому предлагаю вам пользоваться поиском если вас интересует что-то конкретное.
Что описано в главе:
1) Функциональное тестирование
2) Регрессионное тестирование
3) Модульное тестирование
4) Юнит тестирование
5) Системное тестирование
6) Интеграционное тестирование
7) Сквозное тестирование
8) Санитарное тестирование
9) Позитивное тестирование
10) Негативное тестирование
11) Конфигурационное тестирование
12) Кроссбраузерное тестирование
13) Кроссплатформенное тестирование
14) Тестирование установки
15) Тестирование удобства использования
16) Нагрузочное тестирование
17) Автоматизированное тестирование
18) Приёмочное тестирование
19) Черный ящик
20) Серый ящик
21) Белый ящик
22) Комбинирование видов тестирования
23) Отличия системного и интеграционного тестирования в маленьких и больших компаниях
Виды тестирования
Функциональное тестирование
Проблема - «Новые функциональности системы могут работать не так, как это изначально задумывалось».
Давайте представим, что у вас есть релиз №1. Релиз №1 пока что находится на этапе разработки и в нем разрабатывается функционал №1. Можно ли релиз №1 отдать пользователям, как только разработчик закончит писать код (без тестирования)? Да, можно – кто же вам запретит. Но это может потенциально вызвать проблемы.
Вспомните как вы писали диктанты в школе. Наверняка вы, написав диктант, были уверены, что ну вот в этот раз вы точно написали его без ошибок. Точнее даже не так – от диктанта к диктанту вы никогда целенаправленно не оставляли ошибку в написанном тексте и даже иногда перепроверяли его сами за собой, чтобы найти свои же ошибки. А по итогу получали трояк или четверку с комментарием учителя по поводу ваших ошибок.
С разработчиками та же история. Они бы хотели передавать свой код совсем без ошибок, но увы свои ошибки они находят хуже, чем человек со стороны. Для решения данной проблемы было придумано функциональное тестирование.
Функциональное тестирование (Functional Testing) – вид тестирования ПО, направленный на проверку соответствия ПО требованиям.
Регрессионное тестирование
Проблема - «Когда в систему добавляется новый функционал – старый функционал может ломаться».
Теперь представим, что релиз №1 мы проверили функциональным тестированием. Всё работает отлично. Теперь на очереди релиз №2, который добавляет функционал №2 и немного правит функциональность №1 из релиза №1. Вы, проверили релиз №2 функциональным тестированием. Можно ли его отдавать пользователям? Казалось бы – что может пойти не так? Но может.
На примере ситуации из жизни – хоть раз, но вы задавались вопросом «А выключил ли я утюг?» или «А запер ли я дверь?». Ведь и утюг тот же, да и дверь не изменилась, но выходя из дома вы сделали какой-то новый порядок действий и забыли про то, что вы уже сделали. Чтобы удостовериться, что всё закрыто или выключено – вы возвращаетесь и перепроверяете.
Для решения этой проблемы было придумано регрессионное тестирование.
Регрессионное тестирование (Regression Testing)– вид тестирования ПО, направленный на проверку функциональности, которая уже была передана заказчику, на предмет соответствия требованиям.
Модульное тестирование
Проблема – «В систему добавляется новая функциональность – как бы поскорее бы ее проверить, что она работает?»
Снова включаем воображение. Представьте, что вы заказали кухонный гарнитур бежевого цвета. Вам его доставляют домой, но по частям. Сначала привезли напольные модули, а через пару часов привезут навесные. Глядя на напольные модули, вы осознаете, что они не бежевого цвета, а коричневого – то есть совершенно не те, что вы заказывали. Что вы будете делать? Разумеется, позвоните в магазин и скажете, чтобы их заменили на правильные (да и заодно перепроверили какие навесные модули собираются везти). Вы не будете собирать весь гарнитур, расставлять его по кухне и только потом удивляться «ах, как же так – цвет же другой и как я сразу это не заметил» - потому что вы цените своё время.
Также и в разработке ПО – чаще всего программа неявно разделена на какие-то части, которые объединены чем-то общим. Возвращаемся к нашим релизам. Разрабатывается релиз №3 с функционалом №3. Функционал №3 уже можно начать тестировать, просто взаимодействие функционала №3 с функциональностью №1 и №2 проверить нельзя. Например, у нас web-интерфейс, на котором вы нажимаете какие-то кнопки и смотрите на результат, но перейти по ссылкам на web-интерфейсы №1 и №2 не можете. Мешает вам это провести тестирование функционала №3? Нет. Так вперед и с песней.
Компонентное (или Модульное) тестирование (Module Testing)– вид тестирования ПО, при котором тестирование выполняется для каждого компонента / модуля отдельно, без интеграции с другими модулями / компонентами.
Юнит тестирование
Проблема – «Разработчики часто дорабатывают функции системы – как убедиться в том, что новые функции системы не ломают старые, но на самом раннем этапе (пока это еще не попало к тестировщикам)?»
Этот раздел специально для тех, кто запутался в терминах «Модульное тестирование» / «Юнит тестирование» / «Компонентное тестирование» и хочет понять «Да кто-ж это такие ваши юнит-тесты».
Вернемся к кухонному гарнитуру. Даже к отдельному его модулю – к навесному. Обычно это шкафчики, которые открываются и закрываются, там много всяких полочек и так далее. Возьмем конкретную и атомарную функцию шкафчика – закрывать дверку шкафчика. Предположим, что на производстве хотят изменить внутренний дизайн шкафчика, из-за которого петли, на которые крепятся дверки, необходимо на пару сантиметров вверх. Согласитесь, было бы странно, если бы по итогу вы получили партию из 1000 шкафчиков, у которых дверь теперь расположена не ровно с основной конструкцией, а на те же два сантиметра выше, чем нижняя часть шкафа. Для того, чтобы это не произошло – при изменении внутреннего дизайна шкафчика – основные функции его перепроверят при первой сборке.
Когда разработчик пишет код – он делает примерно то же самое. Отдельно взятый компонент системы состоит из еще более мелких составляющих (функции / методы), которые выполняют какие-то максимально простые действия. Например, функциональность №4 состоит из 5 методов (5 кусков кода, которые что-то делают), которые можно проверить отдельно (имея доступ к коду), но в целом эти 5 методов выполняют единую бизнес-логику. Разработчик на каждый из 5 методов напишет по юнит-тесту (еще 5 кусков кода для автоматической проверки уже имеющегося кода), которые будут при каждой сборке проверять работоспособность этих 5 методов.
Юнит тестирование (Unit Testing) – вид тестирования ПО, при котором тестирование выполняется для одного логически выделенного и изолированного элемента системы (отдельные методы или простые функции) в коде.
Важно! Основной плюс для вас, как для тестировщика – вас это тестирование не касается. Не вы будете писать этот код и не вы будете анализировать результаты работы юнит тестов. Особенно на этапе начинающего специалиста.
Системное тестирование
Проблема – «Компоненты системы по-отдельности работают корректно. Но это не значит, что они работают корректно как единая система»
Теперь представим кухню в целом. У вас есть куча модулей – кухонный гарнитур, духовка, стол, холодильник и так далее. Все работает идеально. Вы решаете добавить на кухню раскладывающийся диван, но так как вы научены горьким опытом – проверяете его прямо в магазине. Он тоже работает – и сидеть на нем можно, и раскладывается/складывается он хорошо. Но, когда диван оказывается на кухне, выясняется, что раскладываться диван не может, так как кухня мала – надо либо выносить стол, либо заказывать новый диван. То есть, отдельно «компоненты кухни» работали отлично, но при их объединении что-то идет не так.
При разработке ПО очень часто разные модули системы пишут разные разработчики и есть вероятность что их модули не будут согласовываться между собой. Вам стоит учитывать это при работе.
Системное тестирование (System Testing) – вид тестирования, выполняемого на полной системе, со всеми интегрированными внутренними модулями, с целью проверки соответствия системы требованиям.
Важно! Для понятий «Системное тестирование» и «Интеграционное тестирование» ниже будет отдельный блок, который объяснит отличие этих понятий в маленьких и больших компаниях.
Интеграционное тестирование
Проблема – «Система в целом работает корректно. Но это не значит, что при работе с нашей системой извне не возникнет проблем»
Не будем мы уходить от кухни, уж больно удачный пример. Все компоненты кухни работают отлично. Но проблемы не кончились. Вы решаете добавить систему «умный дом» и скачиваете приложение на телефон. Кухня работает. Приложение работает. Но вот лампочки на вашей кухне не включаются через приложение, потому что они «не умные», т.е. не подходят для такого взаимодействия «умного дома» и вашей кухни. Проблема есть и ее придется решать.
Аналогичная ситуация в разработке ПО – если ваша система интегрирована с другими системами (т.е. вынуждена взаимодействовать с другими системами) есть вероятность, что в момент этой интеграции что-то пойдет не так.
Это касается не только взаимодействия нескольких систем, но и взаимодействия модулей отдельных систем, как показано в примере системного тестирования. Только если системное тестирование это проверка взаимодействия всех модулей как единого целого, то проверка взаимодействия двух конкретных модулей (из множества других) не будет являться системным тестированием
Пример №1: между двумя командами произошло недопонимание, и команда №1 ждала от команды №2 данные в одном формате, а команда №2 неправильно поняла команду №1 и отправляет данные иначе. В итоге взаимодействие систем не работает
Пример №2: между двумя разработчиками произошло недопонимание, и разработчик №1 ждал от разработчика №2 данные в одном формате, а разработчик №2 неправильно понял разработчика №1 и отправляет данные иначе. В итоге само взаимодействие компонентов систем не работает.
Интеграционное тестирование (Integration Testing) – вид тестирования, предназначенный для проверки взаимодействия между компонентами системы или проверки взаимодействия между различными системами.
Важно! Для понятий «Системное тестирование» и «Интеграционное тестирование» ниже будет отдельный блок, который объяснит отличие этих понятий в маленьких и больших компаниях.
Сквозное тестирование
Проблема – «Если в бизнес процессе участвует очень много систем – как убедиться в том, что процесс пройдет успешно от начала до конца?»
Итак, сферическая кухня в вакууме (ну разумеется еще в магазине) собрана. И даже умный дом работает – лампочки включаются и выключаются. Вы привозите ее домой, а умный дом всё еще не работает. Почему так? В магазине же работало. А потому что вы привезли ее в деревню, а ваш мобильный оператор в ней не ловит связь. Соответственно приложение умного дома не может связаться с вашими лампочками, чтобы ими управлять, так как что-то в общем сквозном процессе пошло не так, как задумывалось.
При разработке ПО бывают и такие ситуации. Чаще всего что-то похожее возникает, когда в компании есть какая-то большая экосистема из систем, где каждая из систем выполняет свою конечную функцию, но при этом связана с общим бизнес-процессом. Или же такая ситуация может возникнуть в рамках одной системы, если бизнес-процесс в ней проходит очень длинный путь.
Сквозное тестирование (E2E, End to End Testing) – вид тестирования, предназначенный для проверки работы системы от начала до конца с точки зрения пользователя.
Смоук тестирование
Проблема – «Необходимо в кратчайшие сроки выяснить – работает ли в принципе система?»
Давайте представим, что вам очень сильно не повезло с командой «разработчиков». На вашей кухне от сборки к сборке то чайник не включается, то свет. Иногда шкафчик не открывается, а временами микроволновка вроде работает, но не греет. В новой сборке нет возможности предполагать какая поломка ждет вас сегодня.
Разберем три элемента кухни, несколько функций этих элементов и время на проверку этих функций для большей наглядности.
Элемент кухни №1: Микроволновка.
Функция №1 элемента №1 - Включиться от эклектической сети. (5 минут на проверку)
Функция №2 элемента №1 – Разогреть пищу. (5 минут на проверку)
Функция №3 элемента №1 – Включить таймер работы микроволновки (греть пищу фиксированное количество времени). (5 минут на проверку)
Элемент №2: Посудомойка.
Функция №1 элемента №2 - Включиться от сети. (10 минут на проверку)
Функция №2 элемента №2 – Помыть посуду. (120 минут на проверку)
Функция №3 элемента №2 – Изменять режим мытья посуды, в зависимости от типов загрязнения. (120 минут на проверку)
Элемент №3: Электрочайник.
Функция №1 элемента №3 - Включиться от сети. (5 минут на проверку)
Функция №2 элемента №3 – Разогреть воду. (5 минут на проверку)
Функция №3 элемента №3 – Светиться, если включен разогрев воды (вот такой на нашей кухне мечты модный чайник). (1 минута на проверку)
Внимательный читатель обратил внимание что у каждого элемента есть функции, которые очевидно важнее остальных. К этой мысли мы медленно, но уверенно приближаемся.
Какие у нас есть опции для проверок – например, проверять каждый элемент и функцию последовательно. Рассмотрим худший вариант – из раза в раз чайник не греет воду. Из раза в раз вы тратите 15 минут на проверку микроволновки и 250 минут на проверку посудомойки, чтобы выяснить что чайник даже не начинает греть воду. Итого затрачено 265 минут.
Хотим сэкономить время – выделяем критически важные функции. Это функция №1 и №2 для каждого из элементов. Получается, что на проверку микроволновки – 10 минут, на проверку посудомойки – 130 минут, чтобы выяснить что чайник не работает. Суммарно 140 минут, что сэкономило нам практически 2 часа на проверку одной сборки. А что, если функций не 3, а 30. Или если сборок будет не 1, а 10?
В процессе тестирования ПО аналогично. Есть более важные бизнес-процессы, есть менее важные бизнес-процессы – если важный бизнес-процесс сломан, а его починка потенциально будет влиять на менее важный бизнес-процесс – возможно имеет смысл переключиться на другие задачи и дождаться исправлений, чтоб не тратить время зря.
Смоук тестирование (Smoke Testing, реже Дымовое тестирование) – вид тестирования ПО, предназначенный для проверки того, что программа запускается и выполняет свои основные функции.
Санитарное тестирование
Проблема – «Необходимо в кратчайшие сроки убедиться – работает ли конкретная функция системы после доработок»
Проблема по смыслу очень близка к предыдущей и не просто так. В смоук тестировании обсуждалась ситуация, когда точно не было известно, что конкретно может сломаться в системе и была необходимость проверять каждый ее модуль. Предлагаю разобрать данный пример на конкретном элементе кухни – чайнике. Имеются следующие вводные:
1) Чайник необходимо передвинуть на новое место на столешнице.
2) Электрочайник достаточно старый и у него плохой провод. Следовательно, при перестановке чайника на определенную дальность от розетки – он перестанет работать.
Заметьте – ничего кроме конкретного модуля кухни (в виде чайника) не изменяется. Вы это абсолютно точно знаете. Получается, что не имеет смысла при перестановке чайника с места на место проверять как работает микроволновка или посудомоечная машина. Однако функций у чайника сильно больше, чем мы упомянули в смоук тестировании. Он должен включаться / греть воду / выключаться автоматически при нагреве воды до 100 градусов / выключаться по требованию / открывать крышку / закрывать крышку / вмещать в себя воду и так далее… В общем функций много. И эти функции имеют разную значимость для вас, как для пользователя чайника, а значит будут иметь разный приоритет проверок для вас, как для инженера по тестированию.
В тестировании ПО вам тоже придется столкнуться с таким видом тестирования. Его называют «Санити тестирование» (от слова Sanity- здравомыслие) или «Санитарное тестирование». По правде говоря – его чаще просто проводят и никак не обозначают. От многих инженеров вы даже не сможете добиться определения этого вида тестирования, на столько этот вид тестирования проводится «подсознательно».
Санитарное тестирование (Sanity Testing, Санити тестирование) – вид тестирования ПО, предназначенный для повторной проверки того, что конкретная функция системы работает согласно предъявляемым к ней требованиям после внесения изменений в эту функцию.
Проще всего запомнить этот вид тестирования как что-то промежуточное между смоук тестированием и регрессионным тестированием, но относящиеся к конкретной функции / модулю системы.
Позитивное тестирование и негативное тестирование
Проблема – «Как потратить время на проверку именно того, что необходимо пользователю в первую очередь?»
Снова включаем воображение. Вы, как пользователь, купили электрический чайник. Что произойдет в первую очередь, когда вы с покупкой придете домой? Правильно – вы захотите убедиться «А работает ли чайник?». Конкретный купленный чайник состоит из двух частей:
1) Сам чайник с ёмкостью для воды, нагревательным элементом, кнопкой включения/выключения и крышкой.
2) Подставка электрочайника с разъемом для установки чайника и шнуром с вилкой для подключения в розетку.
Теперь предлагаю вам остановиться в прочтении статьи и представить свои реальные действия при проверке чайника. Представьте весь свой путь, так сказать «от» и «до», после которого вы бы смогли сказать: «Ну, этот чайник точно работает».
Если вы решили не останавливаться и читать дальше – всё же остановитесь и представьте, иначе этот пример не возымеет нужного эффекта.
Ну а теперь переходим к сути. Я, как совершенно обычный человек, выполнил бы следующие действия, чтобы убедиться в работоспособности чайника:
1) Достал бы чайник из коробки.
2) Подключил бы подставку чайника в розетку.
3) Залил необходимый минимальный уровень воды в чайник.
4) Нажал на кнопку включения, ожидая что начнется нагрев воды.
5) Дождался бы закипания воды и автоматического выключения чайника.
Если вы себе представили такой же «пользовательский путь» - поздравляю, вы уверенный пользователь чайника. Но что насчет следующих проверок?
1) Попробовать включить чайник с уровнем воды ниже, чем минимальный.
2) Попробовать включить чайник без воды.
3) Попробовать включить чайник, который не установлен на подставку.
4) Попробовать выключить чайник, пока вода не закипела
5) Попробовать включить подставку для чайника в евро-розетку с тремя гнездами.
Если у вас возникает вопрос «Да кто вообще в здравом уме будет таким заниматься?» - вы будете удивлены, но 1 пользователь из тысячи может учудить что-то такое. И наша система «электрический чайник» как минимум не должна ломаться, а как максимум предотвратить нежелательное поведение (путем защиты от дураков). Это два разных типа сценариев – позитивные и негативные.
Позитивный сценарий – это сценарий, в котором имитируются действия, которые выполняло бы большинство пользователей при взаимодействии с продуктом. В позитивном сценарии мы, как инженеры по тестированию, оперируем валидными данными и пытаемся выполнить действия, которые система должна уметь выполнять.
Негативный сценарий – это сценарий, в котором в систему подаются заведомо недопустимые входные данные или производятся попытки выполнить недопустимые действия, чтобы проверить стабильность работы системы и убедиться, что такую ситуацию система обрабатывает корректно.
Пример с чайником нужен был, чтобы донести до вас простую мысль. Позитивные проверки приоритетнее негативных. Позитивные сценарии более вероятны в реальной жизни и больше важны для пользователя. Системы создаются для того, чтобы пользователи их использовали по назначению, а не пытались сломать. Не забывайте об этом при создании и выполнении своих тестовых сценариев.
Позитивное тестирование (Positive Testing) – вид тестирования, направленный на проверку действий, которые бы выполнял конечный пользователь продукта.
Негативное тестирование (Negative Testing) – вид тестирования, основанный на попытке выполнения недопустимых действий или использования недопустимых данных с целью убедиться, что система способна обработать такие действия или данные.
Конфигурационное тестирование
Проблема – «Нужно быть уверенным, что не возникнет проблем с конфигурацией серверов / клиентов, даже если само ПО выполняет свои функции»
Тут нам придется коснуться вскользь клиент-серверной архитектуры приложений, которая будет разобрана в отдельной главе. И сделаем мы это (…барабанная дробь…) на примере кухни. Надо понимать, что в традиционном представлении клиент-серверная архитектура состоит из трёх основных частей:
1) Клиент (источник запросов)
2) Сервер (часть системы, отвечающая за исполнение бизнес-логики)
3) База данных (часть системы, которая является хранилищем информации, представляющей полезность для исполнения бизнес-логики)
В примере с кухней в качестве клиента выступает «квартира + кухня + Вы, как собственник квартиры», в качестве сервера «многоквартирный дом + все коммуникации многоквартирного дома + управляющая компания», а в качестве базы данных будет выступать «бухгалтерия + реестр собственников + список счетов на оплату воды». Теперь перейдем к примерам.
Пример №1:
Кухня проверена еще на этапе магазина – сделана точная копия вашей кухни – свет работает, вода течёт, всё помещается и включается – ну разве не сказка? Вы перевозите кухню в свою квартиру, монтируете и обнаруживаете, что горячая вода из крана не течёт. На чьей стороне проблема?
Предположим, что на вашей – на уровне квартиры (т.е. клиента) не был открыт вентиль с горячей водой. Вы открываете вентиль с горячей водой – кухня заработала. Конфигурация на уровне клиента исправлена.
Пример №2:
Аналогичная ситуация: в магазине всё работало, а у вас в квартире не течёт горячая вода. Вы открываете вентиль горячей воды – всё еще не работает. Более того, вы узнали у соседей и у них тоже не работает горячая вода. Звоните в управляющую компанию и выясняете, что горячую воду забыли включить на уровне всего многоквартирного дома. Воду включают – проблема решена. Конфигурация на уровне сервера исправлена.
Пример №3:
Кухня работает и в магазине, и у вас в квартире – выдыхаем. Но вы, как и ваши соседи обратили внимание, что с мая вам начали приходить неадекватно большие платежи за холодную воду, и крайне малые платежи за горячую воду. Вы предъявляете свои возмущения управляющей компании и узнаете, что с их стороны проблемы нет – показания горячей воды и холодной в бухгалтерию подаются корректно. При разборе инцидента все-таки удается выяснить, что проблема на стороне бухгалтерии – там новый бухгалтер, который менял местами показания холодного и горячего водоснабжения. Проводятся разъяснительные работы, перерасчет платежей – проблема на стороне базы данных решена.
При разработке ПО происходят аналогичные проблемы. На всех трех сторонах клиент-серверного взаимодействия могут быть реализованы различные настройки, либо могут использоваться разные версии «вспомогательного» ПО, при изменении которых возможно непосредственное влияние на успешность работы бизнес-процессов.
Давайте теперь посмотрим примеры из тестирования.
Пример №1 – проблема на стороне клиента:
Пользователь №1 работает с web-приложением для просмотра бессмысленных видео. В настройках своего профиля он выставил галочку «Сохранять историю просмотров».
Пользователь №2 работает с тем же web-приложением и жалуется, что в истории просмотров видео пустота и он не может найти то самое видео, которое ему так понравилось. Выясняется, что в конфигурации своего профиля галочку «Сохранять историю просмотров» он не проставил.
Пример №2 – проблема на стороне сервера:
Серверная часть web-приложения написана на языке программирования Java, на версии N. Версия морально устарела и требует обновления. Команда обновляет версию до N+1. На стендах разработки и тестирования всё работает отлично. На стенде приёмо-сдаточных испытаний приложение не запускается. Потому что на сам сервер, где пытается запуститься приложение не установлено необходимое для работы версии N+1 Java сопутствующее ПО (например jdk).
Пример №3 – проблема на стороне сервера:
При доработке серверной части web-приложения появилась настройка, которая отвечает за включение / выключение функционал X. Настройка располагается в конфигурационном файле. Для простоты представьте себе обычный текстовый документ с определенным названием, в котором написано одно из двух – либо «включена», либо «выключена». В промышленной эксплуатации функционал N не работает. Инженеры по сопровождению забыли положить на сервер конфигурационный файл, а при отсутствии конфигурационного файла система по умолчанию считает, что необходимо работать с выключенным функционалом X.
Пример №4 – проблема на стороне базы данных:
Базы данных также имеют версии. Представьте, что вам необходимо обновить версию вашей БД с версии N до версии N+1. При обновлении вы выясняете, что один из важных бизнес-процессов в системе перестал работать на этапе записи данных в базу. Просто в доработке N+1 версии БД немного исправили синтаксис запросов к БД и из-за этого функционал перестал работать. Как же хорошо, что вы знаете, что надо тестировать конфигурацию.
В сухом остатке получаем следующее:
Конфигурационное тестирование (Configuration Testing) – вид тестирования, направленный на проверку работы программы при различных конфигурациях системы
Кроссбраузерное тестирование
Проблема – «Одно и то же web-приложение может по-разному работать в разных браузерах»
В качестве клиента в web-приложениях выступают интернет-страницы, которые открываются в каком-то браузере. И, вы будете удивлены, но не все браузеры работают одинаково. Сами браузеры это по сути программы, которые имеют разные «движки», скрывающиеся за красивыми формочками, да и вообще эти программы писались разными командами разработки. Из-за этого одно и то же web-приложение может по-разному отображаться в разных браузерах.
Чаще всего проблемы использования разных браузеров заключаются в различающейся верстке страницы, отображении шрифтов / стилей, выравнивании изображений и так далее. Реже случаются более фатальные проблемы, когда в конкретном браузере (чаще всего это устаревший IE) какой-то функционал вообще не работает.
Что делать с этой проблемой?
Всё просто – на уровне нефункциональных требований к продукту выставляется требование по браузерам, в которых должно работать ваше приложение. Если это внутреннее приложение компании – вам повезло, список браузеров вообще может ограничиться каким-то одним официально-используемым браузером компании. Если это приложение для широкого доступа (когда весь интернет может использовать ваше приложение) – аналитики совместно с бизнесом проводят исследование на тему «Какие браузеры чаще всего используют наши пользователи?» и в результате выставляют нефункциональное требование в виде списка браузеров, а вы затем проводите кроссбраузерное тестирование.
Увы, на этом мои познания в кроссбраузерном тестировании заканчиваются, так как мне не довелось тестировать web-приложения, которые расположены в открытом доступе всем пользователям. Но тем не менее вы теперь в курсе такой проблемы, а в интернете достаточно информации про данный вид тестирования и инструментах, которые облегчают это тестирование.
Кроссбраузерное тестирование (Cross-browser Testing) – вид тестирования, направленный на проверку работы web-приложения в разных браузерах.
Кроссплатформенное тестирование
Проблема – «Одно и то же приложение может по-разному работать на разных операционных системах»
Снова вернемся к теме клиент-серверной архитектуры, но уже с другой стороны. Теперь обсудим серверную часть ПО, а точнее то место, на которое эта часть ПО установлена – сервер. Если не вдаваться в подробности виртуализации, контейнеризации и прочих современных решений, то физически сервер из себя представляет большую и мощную железяку (компьютер). И этот большой компьютер в идеале работает в бесперебойном режиме, на него можно установить ваше ПО, чтобы потом попадать в логику вашего ПО через клиент. И как на любом другом компьютере – на сервере будет установлена операционная система, которая будет служить в качестве платформы, для всего остального что установлено на сервер.
Основной нюанс заключается в том, что приложения могут работать по-разному на разных ОС. Более того – они могут работать по-разному на разных версиях одной линейки ОС. Чтоб недалеко ходить за примером – недавний пример из жизни. Захотел автор поиграть на Windows 10 в игру своего детства – Hogs of War, в которую он играл когда-то на Windows XP. "Хотелка" автора не была удовлетворена, так как игра просто не в состоянии запуститься на Windows 10 (это официально утверждают даже разработчики). Дело во «внутренней кухне» приложений и операционных систем.
Это все должно навести вас на следующую мысль. Если ваше ПО переезжает с одного сервера на ОС №1 на другой сервер на ОС №2 – это потенциальная проблема. Нужно регрессионное тестирование. Если ваше ПО переезжает с одного сервера на ОС №1 версии №1 на ОС №1 версии №2 – это потенциальная проблема, хотя и меньших масштабов. Нужно регрессионное тестирование.
Кроссплатформенное тестирование (Cross-platform Testing) – вид тестирования, направленный на проверку совместимости ПО с различными операционными системами или их версиями.
Тестирование установки
Проблема – «Необходимо убедиться, что система сможет корректно запуститься на целевой конфигурации серверов и на целевых операционных системах»
Снова включаем воображение и снова на примере той же кухни. Предположим, что в магазине вы видите, что навесные полки кухонного гарнитура висят на стене. Значит ли это, что они также успешно будут висеть на вашей стене? Вы оплачиваете покупку и привозите кухонный гарнитур домой. Начинаете крепить навесные полки саморезами, идущими в комплекте и… навесные полки не держатся. Выяснилось, что у вас в доме стены покрыты слоем глины, которая не может выдержать необходимый вес, а штатные саморезы слишком коротки, чтобы достать до бревен или шпал.
В процессе разработки ПО примерно такая же ситуация. Система в целом должна устанавливаться на сервера без ошибок. Однако, высока вероятность того, что что-то пойдет не так. Например, разработчик решил добавить какую-то настройку, которая должна быть выставлена в настройках самого сервера до старта приложения. Локально у разработчика всё работает, так как он знает про эту настройку. А на тестовых стендах установка может пройти неудачно, так как ни вы, ни DevOps инженер не знаете про эту настройку заранее. Догадайтесь что будет при установке финального релиза на боевой контур (если вы проигнорируете данную проблему).
Тестирование установки (Installation Testing) – вид тестирования ПО, предназначенный для проверки успешной установки и настройки, а также обновления или удаления программного обеспечения.
Тестирование безопасности
Проблема – «Нужно быть уверенным, что ваше ПО безопасно и для вашей компании, и для ваших пользователей»
Предположим, что на вашей кухне при определенном положении ручки смесителя крана начинает подтекать вода. Вы можете это игнорировать, но в определенной ситуации это может привести к негативным последствиям. Например, вы улетели на 2 недели в отпуск в Турцию, а в сочетании с подтекающим краном еще и засорился слив. Как закономерный итог – получаем потоп в квартире. Или пример еще хуже – электрические провода, идущие до розеток в кухне ничем не скрыты и оголены. В определенных обстоятельствах это может стоить вам здоровья, если не жизни. Ну или самый банальный пример – дверь в вашу квартиру можно открыть совершенно любым ключом, а не только вашим.
При разработке ПО также пытаются обеспечить безопасность работы этого самого ПО. Причем двухстороннюю (хотя, честно говоря, всё больше направлено именно на прибыль компании):
1) Обеспечить безопасность данных пользователей, работающих в системе, так как низкий уровень безопасности может привести к репутационным издержкам (что в итоге, разумеется, влияет на прибыль компании).
2) Обеспечить безопасность данных компании, так как это может привести к негативным финансовым последствиям.
Также надо понимать пару простых истин:
1) Пользователей ПО, которые хотят что-то украсть или получить доступ к чужим данным сильно меньше, чем обычных пользователей.
2) «Обеспечение безопасности данных компании» — это фраза не только о том, что кто-то за пределами компании пытается получить данные, но и о разграничении доступа к данным сотрудникам, имеющим разные «роли» в компании.
3) Обеспечение безопасности — это не только какие-то специализированные инструменты (протоколы шифрования / многофакторные аутентификации), но и банальная человеческая внимательность к деталям.
Сначала хорошие новости – для тестирования безопасности существуют специализированные классы специалистов.
Один из классов – это тестировщики безопасности. Их называют «Инженер по тестированию безопасности». Именно они разбираются в целой куче информации о том, как нехорошие «хацкеры» пытаются взломать ваше ПО, и именно они знают как использовать специализированное ПО для тестирования безопасности.
Второй из классов специалистов – инженеры по кибербезопасности. Это внутренние специалисты компании, которые внимательно следят, чтобы рядовой менеджер Вася не получил доступ к тем же данным, что и топ-менеджер Пётр Алексеевич. Также именно эти специалисты следят, чтобы в компании использовались современные протоколы шифрования для обмена данными и инструменты для разработки ПО, в которых отсутствуют уязвимости (не используй уязвимое ПО при разработке своего ПО, чтобы не сделать своё ПО уязвимым).
Так как мои статьи направлены больше на функциональных тестировщиков web-приложений, мы не будем глубоко вникать в тонкие материи деятельности этих специалистов. Важно понимать, что при тестировании web-приложения не надо забывать об аспекте безопасности этого приложения.
Давайте рассмотрим пример:
У вас есть форма авторизации в электронной почте с двумя полями ввода «Логин» и «Пароль». Допустим, если пользователь заполнил оба поля и ввел несуществующий логин – система отобразит ему ошибку «Введен неправильный логин». Если пользователь заполнил оба поля и ввел корректный логин, но неправильный пароль – система отобразит ему ошибку «Введен неправильный пароль».
Казалось бы – что здесь не так? Система не пускает пользователя с некорректным паролем – всё безопасно. Да, безопасно, но для 99,99…9% пользователей. А злоумышленник, за счет явной текстовки ошибки «Введен неправильный логин» может рано или поздно подобрать «правильный логин». А затем будет делом техники подобрать «правильный» пароль. Изменение текстовки ошибки на «Введен неправильный логин ИЛИ пароль» пусть незначительно, но обезопасит вашу систему, так как подобрать правильный логин станет сложнее.
Тестирование безопасности (Security Testing) - вид тестирования ПО, направленный на проверку безопасности системы и выявление уязвимостей и угроз, а также на анализ рисков, связанных с обеспечением целостного подхода к защите приложения от атак хакеров, вирусов, несанкционированного доступа к конфиденциальным данным или функциям системы.
Тестирование удобства использования
Проблема – «Программное обеспечение должно не только успешно работать, но и должно быть удобным в использовании»
Возможно, вы меня проклянете, но мы возвращаемся к кухне. Представьте, что в вашей квартире холодильник находится не на кухне, а в спальне. На сколько это удобно, если вы ежедневно вынуждены готовить по 4 раза в день? Да и не просто удобно, а сколько вы потратите на это времени? Предположим, что одну минуту на одну готовку, т.е. 4 минуты в день, 1460 минут в год, т.е. 24,3 часа в год, т.е. плюс-минус один потерянный день в жизни за год. А всего лишь стоило поставить холодильник также, как у всех – на кухне. Потому что это удобно.
В разработке программного обеспечения это называют «пользовательский опыт». Весь процесс использования приложения пытаются сделать максимально удобно для пользователя. Причем под словом «пользователь» здесь мы понимаем не только людей, которые кликают по кнопкам и заполняют поля в браузере, но и другие системы, которые обмениваются сообщениями с нами. Т.е. система должна быть сделана примерно так:
- Элементы web-страницы были интуитивно-понятно расположены;
- Для выполнения какого-то конкретного действия пользователь приходилось совершать минимальное количество сторонних действий (например, переходить на другие формы)
- Должна быть «защита от дурака», т.е. при совершении действий пользователь совершать минимальное количество ошибок.
Как инженер по тестированию, вы не должны забывать об удобстве использования системы. Если систему можно сделать удобнее – лучше бы это сделать. Например, у вас на форме есть поле ввода даты, которое почему-то принимает и буквы, и спецсимволы. Зачем? Если поле будет принимать только цифры и символы разделителей – будет меньше ошибок со стороны пользователей и они сэкономят время.
Тестирование удобства использования (Usability или User Experience, или UX Testing) – вид тестирования, направленный на проверки степени удобства использования, понятности и привлекательности для пользователей разрабатываемого продукта.
Нагрузочное тестирование (Тестирование производительности, Тестирование стабильности, Стресс тестирование)
Проблема – «Успешная работа ПО при малом количестве пользователей не гарантирует успешную работу при большом количестве пользователей»
Устали от примеров с кухней? У меня есть еще один. Включаем воображение. Вы живете один, но на случай гостей купили себе столовых приборов по 4 экземпляра: 4 ложки, 4 вилки, 4 глубоких тарелки и так далее. Ваша потребность удовлетворена – к кухне претензий нет. Но вот ваши родственники решили навестить вас, чтобы вживую оценить ремонт на кухне и в гости приехали мама, папа, дедушка и бабушка. Все, включая вас устали, хотят кушать и на обед у вас суп. Получается, что кому-то из вас пятерых не хватит тарелки и он останется голодным. Поздравляю – ваша кухня только что не прошла нагрузочное тестирование.
Новостей несколько – как хороших, так и плохих. Хорошая – для проведения нагрузочного тестирования существует класс тестировщиков, которых называют «инженеры по нагрузочному тестированию». Плохая – факт существования нагрузочных тестировщиков не исключает необходимости понимания «что такое нагрузочное тестирование» в целом. И еще одна плохая – нагрузочное тестирование дополнительно разделяется на несколько типов. И еще одна хорошая – все подвиды нагрузочного тестирования разбирать не придется, оставим это профессионалам.
Разберемся с вопросом «зачем же знать виды нагрузочного тестирования, если для этого есть отдельные сотрудники?», прежде чем разбирать эти самые виды. По факту всё сводится к деньгам.
Во-первых, процесс нагрузочного тестирования (далее сокращенно НТ) – это крайне дорогостоящий процесс с точки зрения инфраструктуры. Для тестовых стендов НТ выделяются дорогие и производительные сервера, которые плюс-минус соответствуют промышленным серверам.
Во-вторых, процесс нагрузочного тестирования – это дорого с точки зрения фонда оплаты труда. Для НТ нанимаются дорогостоящие специалисты (среднестатистический специалист НТ зарабатывает больше, чем инженер по функциональному тестированию). Для успешной работы инженера по НТ ему необходимо знать места системы и бизнес-процессы, которые потенциально наиболее подвержены нагрузке. При этом погруженность в сами части системы и логику бизнес-процессов у инженера НТ сильно меньше, чем у остальной части команды. А так как Вы будете непосредственной частью команды – Вы сможете консультировать специалистов НТ по процессам системы, тем самым экономя время и деньги.
В-третьих, умение выявить проблему, связанную с нагрузкой до этапа НТ поднимет вас в глазах вашего менеджмента и, возможно, будет дополнительной мотивацией для начальства рассмотреть увеличение вашей заработной платы.
В-четвертых, иногда процесс НТ отсутствует вовсе. Тут работает концепция «предупрежден – значит вооружен». Знание возможных проблем с нагрузкой позволит вам лишний раз задуматься над теоретическим возникновением данных проблем по вашим задачам. Чем меньше дефектов по вашим задачам в промышленной эксплуатации – тем лучше ваша репутация, как инженера, и тем лучше ваша заработная плата.
Теперь разберем основные виды НТ, которые на мой субъективный взгляд необходимо знать Вам.
Для удобства объяснения я возьму систему, которая сильнее подвержена нагрузке, чем Ваша кухня. Да-да, выдыхаем. Система будет состоять из следующих частей:
1) Ресторан, обслуживающий посетителей. Количество посетителей в час равно 40. Максимальная вместимость – 60 посетителей.
2) Ресурсы ресторана в плане тарелок на кухне. Количество доступных тарелок равно 80.
3) Кухня ресторана, с нерасторопным сотрудником посудомойщиком. Производительность мытья тарелок у посудомойщика равна 2 тарелки в час (т.е. 1 тарелка за 30 минуту).
4) Условия работы ресторана. Ресторан ровно в начало каждого часа запускает посетителей, которые ровно один час проводят прием пищи ровно из одной тарелки. Данное условие необходимо для упрощения объяснения.
Производительность.
Что видно из этих условий невооруженным взглядом? То, что еще до запуска ресторана в работу – нас не устраивает производительность посудомойщика, так как он становится «узким местом» нашей системы. У нас нет необходимости открывать ресторан, чтобы через 2 часа (когда закончатся тарелки) убедиться, что посетители ресторана недовольны.
В информационных системах аналогично. Мы, как пользователи, достаточно привередливы к скорости работы приложений. Если оформление заказа еды в приложении будет отрабатывать 30 минут – вы просто-напросто уйдете к конкурентам, где приложение работает быстро. На этапе аналитики часто закладывается допустимое время отклика конкретного функционала. Вам же, как инженеру по тестированию, необходимо обращать внимание на скорость работы функционала системы. И если вы выявили функционал, который по какой-то причине стал работать медленно – это тревожный звоночек, о котором необходимо уведомить коллег.
Стабильность.
Предположим, посудомойщика заменили. Производительность нового посудомойщика равна 40 тарелок в час. Звучит идеально – можем запускаться? Хотелось бы, но нет. Дело в том, что это производительность сферического посудомойщика в вакууме – она не может быть постоянной на протяжении рабочего дня. На эту производительность воздействует множество факторов – от усталости самого посудомойщика до того на сколько окружающие его условия позволяют ему выполнять свою работу. Предположим, что производительность посудомойщика в середине рабочего дня снижается до 39 тарелок в час. Тут начинается проблема со стабильностью работы ресторана. Сама проблема изображена на рисунке:
Данная ситуация приводит к тому, что функция «мытьё тарелок» деградирует с течением времени, что приводит остальные части системы «ресторан» в неработоспособное состояние. Характерно в этой ситуации то, что вам всегда необходимо достаточно времени, чтобы выявить проблему.
В программном обеспечении тоже самое. Ваши приложения не должны деградировать с течением времени. Вам необходимо точно знать, что в ПО отсутствуют слабые места, которые могут привести к деградации производительности высоконагруженных процессов. Как инженер по функциональному тестированию вы должны задаваться вопросом при тестировании функционала - «Сколько процессов системы или пользователей будет использовать данный функционал?». Если ответом на этот вопрос будет значение, которое сильно выше, чем для среднестатистических процессов в системе – такой функционал стоит рекомендовать к проведению нагрузочного тестирования.
Стресс.
Предположим, что посудомойщика заменили на посудомоечную машину. Теперь у нее стабильная производительность равная 50 чистых тарелок в час. Более того – наученные горьким опытом – вы закупились тарелками – теперь их 120. Казалось бы – что может еще случиться? Может случиться непредвиденная нагрузка - праздник, час-пик, да что бы то ни было. Напомню – максимальное количество мест в системе «ресторан» равно 60. Наступил короткий момент времени, когда вам необходимо пережить такой наплыв посетителей – ресторан полностью забит. Давайте посчитаем сколько проживет ваша система. Проблема изображена на рисунке:
Данная ситуация говорит о том, что при максимальной загрузке ваша система «ресторан» способна выдержать 3 часа, пока не начнется деградация производительности.
В программном обеспечении это называется стресс-тестирование. На систему подается максимальная ожидаемая нагрузка с целью определить как долго система проживет, т.е. сколько в теории у вас есть время на реагирование на такую ситуацию. Вы же, как инженер по функциональному тестированию должны помнить, что ожидаемая нагрузка на систему не всегда соответствует максимальной. Иногда стоит иметь «запас надежности» по критическому функционалу в плане производительности.
Итого, мы имеем:
Нагрузочное тестирование (НТ или Load Testing, или LT) – вид тестирования, направленный на проверку устойчивости и производительности программного обеспечения под нагрузкой, сопоставимой с реальными условиями в промышленной эксплуатации.
Тестирование производительности (Performance Testing) - вид тестирования ПО (подвид НТ), направленный на проверку производительности программного обеспечения под нагрузкой, с целью определения поведения системы в различных состояния.
Тестирование стабильности (Stability Testing) – вид тестирования ПО (подвид НТ), направленный на проверку производительности программного обеспечения под стабильной, ожидаемой нагрузкой.
Стресс тестирование (Stress Testing) – вид тестирования ПО (подвид НТ), направленный на проверку производительности системы в условиях стресса, а также на проверку способности системы к восстановлению работы после окончания стрессовой нагрузки.
Автоматизированное тестирование
Проблема – «Как меньше времени тратить на действия, которые требуют очень частого повторения?»
Здесь мы и вправду отвлечемся от примеров с кухней. В тестировании, как и в любой другой сфере жизни, стараются внедрять автоматизацию процессов для экономии времени. Чем дольше живёт проект – тем больше в нем становится функционала, тем сильнее функционал взаимосвязан между собой. Это приводит ко следующей ситуации:
1) Набор тест-кейсов, по которым необходимо проводить регрессионное тестирование, растет.
2) Количество новых доработок обычно не меняется, а скорее увеличивается.
3) Частота внедрения релизов не изменяется.
Проблема здесь заключается в том, что регрессионное тестирование, которое не приносит компании новой прибыли, начинает требовать все большее количество времени. Какие есть варианты решения:
Вариант №1. Уменьшить объем регрессионного тестирования. Да, анализ набора регрессионных тест-кейсов и уменьшение этого набора частично может повлиять на ситуацию. Но в перспективе это проблему не решит, так как этот набор будет увеличиваться из релиза в релиз. Сокращать набор радикально, убирая из него критические тест-кейсы – не в интересах инженеров по тестированию, так как именно они в итоге несут ответственность за пропуск дефектов в промышленную эксплуатацию.
Вариант №2. Уменьшить количество новых доработок. Это не вариант, с точки зрения бизнеса. Чтобы продукт продолжал приносить бизнесу денюжки, а вам ваши кровные заработанные крепкие рубли – продукт необходимо постоянно развивать. Также, отсутствие доработок будет значить простой инженеров по разработке, что в свою очередь убыток.
Вариант №3. Изменить частоту внедрений. Этот вариант ситуативный, но использовать его на постоянной тоже нельзя. Продукт вашей компании чаще всего конкурирует с еще каким-то продуктом. Частота внедрений напрямую влияет на скорость доставки новых фич вашим пользователям. И чем быстрее ваша команда доставляет новый функционал до пользователей, тем более конкурентоспособный ваш продукт. А это напрямую влияет на заработанные деньги и на ваши зарплаты.
Вариант №4. Увеличить штат. Это в принципе вариант, но согласитесь, что вы не можете постоянно расширять исключительно из-за регрессионного тестирования, так как фонд оплаты труда не резиновый. Да и по своей сути регрессионное тестирование не приносит новых денег компании, а спасает её от неожиданных убытков, которых может и не быть. А большинство менеджеров достаточно скептически относятся к таким «сомнительным», на их взгляд, затратам.
Вариант №5. Нанять инженера по автоматизации тестирования. Этот вариант мы разберем подробнее.
Разумеется, все упирается в деньги. Но надо понять «как именно» экономятся деньги. Давайте представим, что ваша команда наняла инженера по автоматизации тестирования, который за месяц автоматизировал 10 критичных тест-кейсов, которые суммарно занимали 2 часа прохождения у ручного тестировщика. При этом имеются следующие вводные:
1) Релизный цикл составляет 2 недели. Раз в 2 недели внедрение.
2) Новые тесты не автоматизируются, а инженеру по автоматизации не платится заработная плата.
3) Старые, автоматизированные тест-кейсы не изменяются (т.е. эти 10 автоматизированных тестов будут работать всегда)
Считаем выгоду. Мы имеем экономию времени и денег 2 часа за 2 недели, т.е. 1 час в неделю. В году 52 недели – следовательно 52 часа экономии в год. Это чуть больше недели полноценной работы ручного инженера по тестированию, которые он может потратить на новые задачи, которые уйдут в промышленную эксплуатацию раньше, чем планировалось и заработают компании дополнительные деньги.
В реальности, инженер по автоматизации тестирования не закончит на 10 тест-кейсах, но и не автоматизирует все ваши регрессионные кейсы. Но если он сократит ваш регресс с нескольких дней до нескольких часов – это уже очень и очень хорошо.
Очень коротко о том, что делает инженер по автоматизации тестирования. На основании какого-то языка программирования пишется программа, цель которой в точности выполнять действия шагов из тест-кейса и проверять ожидаемый результат по каждому из шагов. Т.е. он буквально пытается своей программой заменить действия ручных тестировщиков. Дополнительно он реализует «обвязку» к этой программе в виде удобного для понимания отчета и реализации запуска автотестов другими членами команды.
Автоматизированное тестирование (Automation testing или Auto Testing) – вид тестирования ПО, направленное на экономию времени и усилий, при котором для выполнения тест-кейсов используется специализированное ПО.
Приемочное тестирование
Проблема – «Как убедиться, что команда сделала именно то, что хотел заказчик?»
Вот мы и подошли к завершающему этапу. Давайте представим, что кухня, о которой на протяжении главы шла речь – это не ваша кухня, а кухня, которую вы изготавливаете «под ключ». Вы предусмотрели совершенно все и перепроверили – кухня соответствует требованиям. Но это не значит, что эта кухня такая, какую хотел заказчик. Здесь вступает в дело «человеческий фактор». Предположим, когда заказчик объяснял, как он представляет себе кухню, он сказал: «Хочу, чтобы предметы на кухне были в следующем порядке: холодильник, раковина, столешница, плита, столешница с микроволновкой и чайником, шкаф». На кухне всё в таком порядке. Только заказчик хотел, чтобы предметы располагались в этом порядке «справа налево», а вы сделали «слева направо».
При разработке ПО такие ситуации встречаются чаще, чем хотелось бы. Объяснить это можно тем, что иногда заказчики не слишком ответственно подходят к постановкам задач, иногда их слова искажают менеджеры, иногда системные аналитики неправильно понимают полученное ТЗ от заказчика, а иногда разработчики и тестировщики относятся к вопросу не слишком ответственно и не уточняют «а действительно ли мы делаем то, что хотел заказчик?». Наша цель – не искать виновного в том, что команда иногда не понимает заказчика. Наша цель – убедиться в том, что заказчик получит именно то, что он хочет, и убедиться в этом до выхода в промышленную эксплуатацию. Для этого придумали «приёмо-сдаточные испытания» или «приёмочные испытания», или сокращенно «ПСИ».
Хотел бы сказать, что есть какой-то универсальный общепринятый способ их проводить, но его нет. В скольких командах и компаниях я работал – везде способ проведения ПСИ отличается. В некоторых компаниях проведение ПСИ на столько извращено, что вместо демонстрации работы доработок релиза это превращается в демонстрацию доработок инженеру по кибербезопасности.
Не будем о грустном – давайте обсудим то, как в общем виде приёмочные испытания должны проходить (по субъективному мнению автора):
1) Команда фиксирует набор доработок, которые вошли в состав релиза.
2) По каждой из доработок выбираются члены команды, которые владеют наибольшей информацией о доработке. Чаще всего это либо системный аналитик, либо тестировщик.
3) По каждой из доработок выбираются 3-4 наиболее критичных сценария работы функционала.
4) В зависимости от стенда проведения ПСИ выбираются инженеры, которые будут проводить приёмо-сдаточные испытания. Если к контуру ПСИ не имеют доступа аналитики и тестировщики – подключаются инженеры по сопровождению
5) Формируется список участников приёмо-сдаточных испытаний из членов команды, непосредственно участвующих в показе функционала. К ним добавляется заказчик или его представитель. И дополнительно менеджмент команды (IT лид, менеджер продукта, лиды тестирования, разработки, аналитики и сопровождения), чтобы фиксировать замечания, при их наличии.
6) Выставляется онлайн встреча на всех участников.
7) На встрече демонстрируется работа критичных сценариев по каждой доработке релиза и фиксируются замечания, при их наличии.
8) По результатам проведения ПСИ формируется протокол встречи, где зафиксированы её результаты. Также принимается решение – соответствуют ли доработки ожиданиям заказчика и можно ли устанавливать релиз в промышленную эксплуатацию.
Приемочное тестирование (Acceptance Testing или Приемо-сдаточные испытания) – формальный вид тестирования, направленный на определение соответствия системы приёмочным критериям и вынесения решения о приёме приложения стороной заказчика.
«Черный ящик», «Серый ящик», «Белый ящик» или классификация подходов к тестированию по уровню доступа к коду.
Тестирование методами «белого», «серого» и «черного» ящика нельзя называть отдельными видами тестирования, но любой тестировщик должен знать эти понятия. Так как эти методы по своей сути очень близки к теме видов тестирования ПО – их стоит разбирать вместе.
Вернемся к ненавистному примеру с кухней. Какие у вас могут быть «состояния», как у пользователя кухни? Давайте разберем несколько из таких состояний:
1) У вас золотые руки. Вы можете разобрать любую технику или элемент мебели кухни, выяснить в чем проблема, а затем собрать всё обратно. Ваш супруг/супруга полностью одобряют такие манипуляции с элементами кухни.
2) У вас золотые руки. Но ваш супруг/супруга вам не доверяют разбирать/собирать элементы кухни.
3) Вы среднестатистический человек. Если что-то ломается на кухне – вы скорее вызовете эксперта чтобы разобраться. Но если очень сильно понадобится – вы можете попробовать разобраться самостоятельно. Ваш супруг/супруга вам доверяют и одобряют манипуляции с элементами кухни.
4) Вы среднестатистический человек. Всё аналогично предыдущему пункту, но ваш супруг/супруга вам не доверяют разбирать/собирать элементы кухни.
5) Вы среднестатистический человек, который вообще без понятия что и как разбирается и собирается на кухне. Ваш супруг/супруга в принципе не против того, чтоб вы что-то разобрали и починили, но вы сами знаете, что от этого не будет никакого толку.
6) Вы среднестатистический человек, который вообще без понятия что и как разбирается и собирается на кухне. Ваш супруг/супруга категорически против, чтоб вы что-то пытались разбирать или собирать, так как трезво оценивают ваши способности.
Теперь, мы заменим в этих примерах ваше «умение в разборе/сборе элементов кухни» на «умение читать код, написанный на каком-то конкретном языке программирования», а «одобрение супруга/супруги» на «доступ к хранилищу кода». По итогу мы получаем следующие комбинации:
1) Вы отлично умеете читать чужой код. У вас есть доступ к хранилищу кода.
2) Вы отлично умеете читать чужой код. У вас нет доступа к хранилищу кода.
3) Вы сможете при необходимости прочитать какую-то часть чужого кода. У вас есть доступ к хранилищу кода.
4) Вы сможете при необходимости прочитать какую-то часть чужого кода. У вас нет доступа к хранилищу кода.
5) Вы не умеете читать код. У вас есть доступ к хранилищу кода.
6) Вы не умеете читать код. У вас нет доступа к хранилищу кода.
Пункт №1 примера – это тестирование ПО методом «белого ящика». Когда вы можете залезть в самые глубокие недра кода вашего приложения, прочитать этот код и понять его. Более того – вы можете еще на этапе прочтения кода выявить какие-то разногласия с требованиями и подсветить эти моменты разработчику. При получении дефекта – вы можете прочитать лог с ошибкой, найти указание на строчку кода, которая привела к ошибке и разобраться в причине возникновения этой ошибки.
Пункт №3 примера – это тестирование ПО методом «серого ящика». Когда в теории у вас есть возможность прочитать код, вы можете его прочитать, но не факт, что поймете всё. Из прочитанного кода вы сможете сделать какие-то догадки или выводы, которые могут позволить вам локализовать ту или иную проблему.
Оставшиеся пункты: №2, №4, №5 и №6 – это тестирование ПО методом «черного ящика». Это когда или вы не понимаете ничего в языках программирования, или вам не дают доступа до хранилища кода по какой-либо причине. Это не значит, что вы не будете в состоянии локализовать проблему. Просто при локализации проблемы у вас будет отсутствовать опция «попытаться прочитать код».
Тестирование методом белого ящика – это то, к чему стоит стремиться, если у вас цель стать суперспециалистом в области обеспечения качества ПО. Однако, отсутствие навыков чтения кода – не делает вас плохим специалистом. Хочу также отметить, что за 7 лет работы я встретил только 1-2 инженеров по тестированию, которые имели способности для тестирования методом белого ящика.
Комбинирование видов тестирования в реальной работе
Еще один момент, который хочется обсудить по этой теме – это то, что большая часть видов тестирования обычно комбинируется с другими в реальной работе. На этом не принято делать акцент, так как со временем инженер на уровне подсознания начинает понимать какие виды тестирования применяются при решении задачи, но так как читатели только учатся – мы разберем эту тему.
Пример №1. Вам поставлена задача провести регрессионное тестирование конкретного модуля системы. В этом модуле есть настройки на уровне конфигурационных файлов, которые также необходимо протестировать на предмет работоспособности.
Комбинируется: Регрессионное тестирование. Модульное тестирование. Конфигурационное тестирование. Позитивное / негативное тестирование.
Постановка задачи в реальной работе: «Проведи регресс <такой-то> части системы».
Пример №2. После проведенного функционального тестирования новой задачи есть подозрения на то, что могут возникнуть проблемы с производительностью как конкретной задачи, так и системы в целом.
Комбинируется: Функциональное тестирование. Нагрузочное тестирование. Системное тестирование. Позитивное / негативное тестирование.
Постановка задачи в реальной работе: «Надо провести НТ по <указание на новую функциональность системы>».
Пример №3. Вам поставлена задача на проведение тестирование новой функциональности системы. Часть системы будет взаимодействовать с соседней системой и отправлять в нее какие-то данные. Вы решаете провести самые критичные проверки, чтобы понять работает ли функциональность в принципе.
Комбинируется: Функциональное тестирование. Модульное тестирование. Интеграционное тестирование. Смоук тестирование. Позитивное тестирование.
Постановка задачи в реальной работе: «Надо протестировать интеграционную задачу <указание на задачу>».
Из этих примеров следует понять то, что в реальной работе крайне редко (практически никогда) вдаются во все виды тестирования, которые необходимо выполнить. Вы должны уметь самостоятельно понимать по какой задаче какое тестирование необходимо провести, т.е. какие виды тестирования вы будете применять. Именно поэтому надо уверенно понимать тему видов тестирования и то, для решения каких проблем создан тот или иной вид тестирования.
Отличия системного и интеграционного тестирования в маленьких и больших компаниях.
Если вы поищите в гугле «Системное тестирование это» - то вы получите примерно следующее определение на первых N десятках источников:
«Системное тестирование - это этап тестирования программного обеспечения, на котором тестируется полный и полностью интегрированный программный продукт на основе спецификации программного обеспечения»
В положении, относительно других этапов тестирования – системное тестирование в таких источниках идет перед приёмочным тестированием (после модульного и интеграционного), то есть буквально системное тестирование воспринимается как чуть-ли не финальный этап.
Я не утверждаю, что эти источники не правы, но и правы они не для всех. Если ваша первая работа будет в ООО «Собирай и интегрируй», где у вас будет разрабатываться одна система – вы будете железно уверены, что системное тестирование идет позднее интеграционного. Ваши этапы тестирования будут выглядеть примерно так:
Никакого когнитивного диссонанса не происходит. Всё последовательно и соответствует тому, что пишут про интеграционное и системное тестирование. Сначала вы тестируете каждый модуль по-отдельности на этапе модульного тестирования. Затем проверяете интеграцию модулей между собой на этапе интеграционного тестирования. Затем собираете все модули в единую систему и проверяете как она работает в целом, с учетом интеграции с внешней системой. Затем на этапе приёмочного тестирования демонстрируете работу системы в целом заказчику.
А теперь давайте от ООО «Собирай и интегрируй» мы уйдем к одному из мастодонтов отечественного IT – к Сберу, а точнее к его маленькой части. Рассмотрим систему авторизации – вход через Сбер ID. Из открытых источников я взял вот такое изображение:
Представьте, что вы тестировщик этой системы. А теперь представьте, что каждый раз на этапах интеграционного и системного тестирования вам необходимо проверить в том числе и интеграцию с каждой из систем. Не слишком радужные перспективы, не правда ли?
Из-за такого количества систем, их взаимосвязанности, а также в целях экономии времени большие компании немного переиграли процесс, немного забив на терминологию. Переиграли процесс следующим образом – просто поменяли этапы местами – системное тестирование проводят раньше, чем интеграционное. Под системным тестированием понимают тестирование системы в целом и проверку интеграции внутренних модулей системы. А под интеграционным тестированием понимают проверку взаимодействия одной системы с другой системой. При этом интеграционное тестирование с внешними системами проводят только в том случае, если менялись части системы, отвечающие за взаимодействие с внешними системами. Да, такой процесс требует большей осознанности во взаимодействии команд разработки между собой, но при этом очень сильно экономит время.
Следующая часть: Клиент-серверная архитектура для тестировщиков
Поддержать или поблагодарить можете:
Лайком;
Комментарием;
Подпиской на канал;