Добро пожаловать в серию статей «Лидерство в тестировании» от гуру и консультанта по тестированию программного обеспечения Пола Джеррарда. Эта серия призвана помочь тестировщикам с многолетним опытом работы, особенно тем, кто работает в Agile командах, преуспеть на своих должностях руководителя тестирования и управления.
В предыдущей статье мы рассмотрели меняющуюся роль тестировщиков и способы улучшения сотрудничества с коллегами. В этой статье мы углубимся в тонкости тестирования производительности, надежности и управляемости веб-приложения. То есть тестирование сервисов.
На этой неделе мы рассмотрим тестирование сервисов для веб-приложений.
Начнем.
Что такое тестирование сервисов?
Качество сервиса, предоставляемого веб-приложением, можно определить, включив в него все его атрибуты, такие как функциональность, производительность, надежность, удобство использования, безопасность и т. д.
Однако для наших задач мы выделяем три конкретные цели, которые попадают под пристальное внимание тестировщиков, которые будут проводить «тестирование сервисов». Вот эти цели:
Производительность: сервис должен реагировать на запросы пользователей, поддерживая при этом возложенные на него нагрузки.
Надежность: если он спроектирован устойчивым к сбоям, сервис должен быть надежным и/или продолжать предоставлять сервис даже в случае сбоя.
Управляемость: сервис должен быть управляемым, настраиваемым или изменяемым без заметного для конечных пользователей ухудшения сервиса. Тестирование управляемости или операций направлено на демонстрацию того, что процедуры администрирования, управления, резервного копирования и восстановления системы работают эффективно.
Во всех трех случаях необходимо имитировать пользовательскую нагрузку для эффективного проведения тестов. Цели производительности, надежности и управляемости существуют в контексте реальных клиентов, использующих сайт для ведения бизнеса.
Время отклика (в данном случае время, необходимое одному системному узлу для ответа на запрос другого) сайта напрямую зависит от ресурсов, доступных в рамках технической архитектуры.
По мере того, как все больше клиентов используют сервис, все меньше технических ресурсов становится доступно для обслуживания запросов каждого пользователя, и время отклика будет ухудшаться.
Очевидно, что сервис, который загружен незначительно, имеет меньше шансов выйти из строя. Основная сложность программного и аппаратного обеспечения нужна для поддержания ресурсов в рамках технической архитектуры при большой нагрузке.
Когда сайт загружен (или перегружен), конфликтующие запросы на ресурсы должны управляться различными компонентами инфраструктуры, такими как серверные и сетевые операционные системы, системы управления базами данных, продукты веб-сервера, брокеры объектных запросов, промежуточное программное обеспечение и т. д.
Эти компоненты инфраструктуры обычно более надежны, чем специально созданный код, требующий ресурса, однако сбои могут происходить в следующих случаях:
Компоненты инфраструктуры выходят из строя, потому что код приложения (из-за плохого проектирования или реализации) предъявляет чрезмерные требования к ресурсам.
Компоненты приложения могут выйти из строя, потому что требуемые им ресурсы не всегда могут быть доступны (вовремя).
Моделируя типичные и необычные производственные нагрузки в течение длительного периода, тестировщики могут выявить недостатки в проектировании или реализации системы. Когда эти недостатки будут устранены, те же тесты покажут, что система устойчива. Тестировщики могут использовать инструменты нагрузочного тестирования для выполнения многих из процессов, описанных ниже.
Во всех сервисах обычно есть ряд критических процессов управления, которые необходимо выполнить для поддержания бесперебойной работы сервиса. Возможно, сервис можно будет отключить для проведения планового обслуживания вне обычных рабочих часов, но большинство онлайн-сервисов работают круглосуточно.
Рабочий день сервиса никогда не заканчивается. Неизбежно должны выполняться процедуры управления, пока сервис работает, а пользователи находятся в системе. Эти процедуры необходимо тестировать во время нагрузки на систему, чтобы убедиться, что они не окажут негативного влияния на работу службы в реальном времени (тестирование производительности).
Что такое тестирование производительности?
Тестирование производительности является ключевым компонентом тестирования услуг. Это способ проверки того, как система работает с точки зрения отзывчивости и стабильности при определенной рабочей нагрузке. Оно работает следующим образом:
Тестирование производительности состоит из ряда тестов при различных нагрузках, когда система достигает устойчивого состояния (нагрузки и время отклика на постоянных уровнях).
Измеряется нагрузка и время отклика для каждой нагрузки, моделируемой в течение 15–30 минут, чтобы получить статистически значимое количество данных.
Отслеживаются и записываются жизненно важные показатели для каждой моделируемой нагрузки. Это различные ресурсы в нашей системе, например, использование ЦП и памяти, пропускная способность сети, скорость ввода-вывода и т. д.
Строится график этих изменяющихся нагрузок в зависимости от времени отклика, испытываемого нашими «виртуальными» пользователями. При построении график выглядит примерно так, как показано на рисунке ниже.
При нулевой нагрузке, когда в системе только один пользователь, весь ресурс принадлежит ему, а время отклика быстрое. По мере того, как мы увеличиваем нагрузку и измеряем время отклика, оно постепенно ухудшается, пока мы не достигаем точки, в которой система работает на максимальной мощности.
В этот момент время отклика для наших тестовых транзакций теоретически бесконечно, поскольку один из ключевых ресурсов системы полностью израсходован, и больше транзакций не может быть обработано.
По мере увеличения нагрузки от нуля до максимума мы также отслеживаем использование различных типов ресурсов, например, использование процессора сервера, использование памяти, пропускную способность сети, блокировки базы данных и т. д.
При максимальной нагрузке один из этих ресурсов исчерпывается на 100%. Этот ресурс является ограничивающим ресурсом, поскольку он заканчивается первым. Конечно, в этот момент время отклика ухудшилось до такой степени, что, вероятно, стало намного медленнее, чем было бы приемлемо.
На графике ниже показано использование/доступность нескольких ресурсов в зависимости от нагрузки.
Чтобы увеличить пропускную способность и/или сократить время отклика системы, следует сделать одно из следующих действий:
Снизить спрос на ресурс, как правило, сделав программное обеспечение, которое использует ресурс, более эффективным (обычно это ответственность разработчиков).
Оптимизировать использование аппаратного ресурса в технической архитектуре, например, настроив СУБД для кэширования большего количества данных в памяти или отдав приоритет некоторым процессам над другими на сервере приложений.
Сделать ресурс более доступным. Обычно путем добавления процессоров, памяти или пропускной способности сети и т. д.
Как вы, несомненно, уже поняли, для тестирования производительности нужна команда людей, которые помогут тестировщикам. Это технические архитекторы, администраторы серверов, администраторы сетей, разработчики и проектировщики/администраторы баз данных. Эти технические специалисты имеют квалификацию для анализа статистики, генерируемой инструментами мониторинга ресурсов, и оценки того, как лучше всего настроить приложение, настроить или обновить систему.
Если вы тестировщик, и вы сами не являетесь экспертом в этих областях, не поддавайтесь искушению притворяться, что вы можете интерпретировать эту статистику и принимать решения по настройке и оптимизации. Следует привлечь экспертов на ранних этапах проекта, чтобы получить их советы и поддержку, а затем, во время тестирования, убедиться, что узкие места выявлены и устранены.
Тестирование надежности/отказоустойчивости
Обеспечение непрерывной доступности сервиса, вероятно, является ключевой целью вашего проекта. Тестирование надежности помогает выявить скрытые ошибки, которые вызывают неожиданные сбои. Тестирование отказоустойчивости помогает убедиться, что разработанные меры отказоустойчивости для ожидаемых сбоев действительно работают.
Тестирование отказоустойчивости
Когда от сайтов требуется быть устойчивыми и/или надежными, они, как правило, проектируются с использованием надежных системных компонентов со встроенными функциями избыточности и отказоустойчивости, которые вступают в действие при возникновении сбоев.
Эти функции могут включать в себя разнообразную сетевую маршрутизацию, несколько серверов, настроенных как кластеры, промежуточное программное обеспечение и распределенную технологию обслуживания, которая обрабатывает балансировку нагрузки и перенаправление трафика в сценариях сбоев.
Тестирование отказоустойчивости направлено на изучение поведения системы в выбранных сценариях сбоев перед развертыванием и обычно включает в себя следующее:
Определение компонентов, которые могут выйти из строя и привести к потере работоспособности (рассмотрение сбоев изнутри).
Определение опасностей, которые могут вызвать сбой и вызвать потерю обслуживания (рассмотрение угроз снаружи).
Анализ режимов или сценариев сбоев, которые могут возникнуть, когда нужна уверенность в том, что меры восстановления сработают.
Автоматизированный тест, который можно использовать для загрузки системы и изучения поведения системы в течение длительного периода.
Тот же автоматизированный тест можно также использовать для загрузки тестируемой системы и мониторинга поведения системы в условиях сбоя.
Метод, называемый анализом дерева отказов (FTA), может помочь понять зависимости обслуживания от его базовых компонентов. Анализ дерева отказов и диаграммы дерева отказов являются логическим представлением системы или сервиса и способами, которыми они могут выйти из строя.
Простая схема ниже показывает связь между базовыми событиями отказа компонентов, промежуточными событиями отказа подсистемы и самым верхним событием отказа сервиса. Конечно, можно определить более трех уровней событий отказа.
Эти тесты необходимо запускать с автоматизированной нагрузкой, чтобы исследовать поведение системы в производственных ситуациях и быть уверенными в том, что приняты необходимые меры для противодействия отказоустойчивости. В частности, тесты показывают следующее:
Как архитектура ведет себя в ситуациях сбоя.
Правильно ли работают средства балансировки нагрузки.
Принимают ли на себя нагрузку средства предотвращения отказов при выходе из строя одного из компонентов.
Работает ли автоматическое восстановление. Работают ли системы после рестарта.
В конечном счете тесты направлены на определение того, поддерживается ли обслуживание конечных пользователей и замечают ли они возникновение сбоя.
Тестирование надежности (или выдержки)
Тестирование надежности направлено на проверку того, что сбои не происходят под нагрузкой.
Большинство аппаратных компонентов надежны настолько, что их среднее время между сбоями может измеряться годами. Тесты надежности требуют использования (или повторного использования) автоматизированных тестов двумя способами для имитации:
Экстремальных нагрузок на определенные компоненты или ресурсы в технической архитектуре.
Длительных периодов нормальных (или экстремальных) нагрузок на всю систему.
Сосредоточившись на определенных компонентах, мы пытаемся нагрузить компонент, подвергая его необоснованно большому количеству запросов для выполнения его предназначенной функции. Часто проще провести стресс-тестирование критических компонентов изолированно с большим количеством простых запросов, прежде чем применять гораздо более сложный тест ко всей инфраструктуре. Существуют также специально разработанные инструменты стресс-тестирования, чтобы упростить процесс для QA.
Тесты на выдержку — это тесты, которые подвергают систему нагрузке в течение длительного периода, возможно, 24, 48 часов или дольше, чтобы найти скрытые проблемы. Скрытые неисправности часто проявляются только после длительного периода использования.
Автоматизированный тест не обязательно должен быть увеличен до экстремальных нагрузок (стресс-тестирование охватывает это). Но нас особенно интересует способность системы выдерживать непрерывное выполнение широкого спектра тестовых транзакций, чтобы обнаружить какие-либо скрытые утечки памяти, блокировки или «состояния гонки».
Тестирование управления сервисами
Наконец, несколько слов о тестировании управления сервисами.
Когда сервис развернут на продакшене, им нужно управлять. Для поддержания работоспособности сервиса необходимо следить за ним, обновлять, делать резервные копии и быстро исправлять, когда что-то идет не так.
Процедуры, которые используют менеджеры сервисов для выполнения обновлений, резервных копий, релизов и восстановления после сбоев, имеют решающее значение для предоставления надежного сервиса, поэтому их необходимо тестировать, особенно если сервис будет подвергаться быстрым изменениям после развертывания.
Конкретные проблемы, которые необходимо решить:
Процедуры не достигают желаемого эффекта.
Процедуры неработоспособны или непригодны для использования.
Процедуры нарушают работу сервиса в реальном времени.
Тесты должны, по возможности, проводиться максимально реалистично.
Немного пищи для размышлений
Некоторые системы подвержены экстремальным нагрузкам при наступлении определенного события. Например, онлайн-бизнес ожидает пиковых нагрузок сразу после рекламы предложений по ТВ, или национальный новостной сайт может быть перегружен, когда выходит важная новость
Подумайте о хорошо знакомой вам системе, которая пострадала от незапланированных инцидентов в вашем бизнесе или в национальных новостях.
Какие инциденты или события могут вызвать избыточную нагрузку в вашей системе?
Можете ли (или могли бы) вы собирать данные из системных журналов, которые дают вам количество выполненных транзакций? Можете ли вы масштабировать это событие, чтобы предсказать критическое событие 1 раз в 100 лет или 1 раз в 1000 лет?
Какие меры вы могли бы применить (или уже применили), чтобы уменьшить вероятность пиков, их масштаб, либо полностью устранить их?