На Хабре уже есть статьи по созданию нагрузочного проекта в Visual Studio. В этом посте хочу рассказать о практической стороне тестирования: какую инфраструктуру мы используем для запуска нагрузки, как делаем замеры производительности, что делаем с полученными данными. Подробные пошаговые инструкции по подготовке проекта и настройке в Visual Studio есть и на MSDN, поэтому не буду заострять на этом внимание, отмечу лишь важные, на мой взгляд, моменты. Поскольку разработка в организации основана на стеке технологий Microsoft, то и для тестирования мы решили использовать возможности Visual Studio, а именно модуль MS Visual Studio Load Testing, который доступен в Ultimate версии VS.
Полигон
Для проведения тестирования подготовлен отдельный полигон, который можно условно поделить на три основные части:
- Генератор нагрузки.
- Сервер Docsvision c сервером БД.
- Отдельная машина, на которой установлен клиент Docsvision.
Для генерации нагрузки используется 5 виртуальных машин, одна из которых является контроллером и управляет распределённой нагрузкой с четырёх нагрузочных агентов. Нагрузка с агентов подаётся на сервер Docsvision (DV), который общается c сервером баз данных DV. Есть ещё одна машина, с установленным клиентом DV, подключена к серверу, с неё замеряется время выполнения типичных операций при различной нагрузке.
На контроллере установлен Visual Studio Ultimate, включающий в себя Visual Studio Test Controller, и лежит проект с тестами на C#. О самих тестах чуть позже. Так как нам нужно запустить на сервер больше, чем 250 виртуальных пользователей, для VS 2010 необходим Microsoft Visual Studio 2010 Load Test Feature Pack. Для более свежих версий VS Ultimate, насколько мне известно, количество виртуальных пользователей не ограничено. Нагрузка между агентами может распределяться неравномерно. Есть возможность запускать агента воообще без нагрузки, только для сбора данных Performance Monitor`а.
На каждый тестовый агент устанавливается Visual Studio Test Agent. Если вы хотите запускать нагрузку только с одной машины, установка Test Agent не понадобится. С помощью Test Agent Configuration Tool на каждом агенте нужно запустить сервис, собирающий счётчики Windows Performance Monitor и запускающий нагрузочные тесты. При конфигурации нагрузочного проекта, можно выбрать, с каких компьютеров и какие мы хотим собирать счётчики (процессор, память, данные с SQL сервера и т.д.). Для этого на них должен быть включён в группу Performance Monitor Users пользователь, под которым запускается нагрузка.
Аналогично на контроллере, через Test Controller Configuration Tool запускается сервис, который управляет агентами и собирает данные со всех машин в одном месте. Агенты подключаются на Test Controller’е.
База данных
Чтобы база для тестирования и характер нагрузки были близки к реальной, мы получили статистику работы пользователей и схему организации данных в базе DV от нескольких наших крупных заказчиков. На этой основе создали структуру папок в нагрузочной базе, заполнили её большим количеством карточек, папок и файлов и составили усреднённый, несколько завышенный, профиль нагрузки. Перед проведением тестирования базу обновляем на билд, для которого хотим провести замеры. Замеры с клиентской машины проводятся на одних и тех же подготовленных карточках, папках, поисковых запросах.
Тесты
Нагрузочный проект состоит из набора тестов, имитирующих деятельность среднестатистического пользователя. Тесты написаны на C# и используют API Docsvision.
По настройкам проекта: мы используем Load pattern «Step» и Test Mix Type «Based on user pace».
Для каждого виртуального пользователя первым выполняется тест ClientStart, открывающий пользовательскую сессию к web-сервису %DVServerName%/DocsVision/StorageServer/StorageServerService.asmx. На протяжении всего теста каждый пользователь выполняет заданное в час количество тестов в соответствии с настройками проекта. По завершению всех тестов и выполняется тест ClientEnd, закрывающий сессию пользователя.
Начальный и конечный тест задается в окне Edit test Mix: окно настройки профиля нагрузки.
Пример теста:
[TestMethod]
public void Регистрация_Документа()
{
string filePath = (string)this.TestProperties["FilePath"];
UserSession session = this.GetUserSession();
Assert.IsNotNull(session);
Document doc = DocumentService.CreateDocument();
doc.MainInfo.Name = "Тестовый документ";
doc.MainInfo.Registrar = StaffService.GetCurrentEmployee();
objectContext.SaveObject<Document>(doc);
//add file and save
DocumentService.AddAdditionalFile(doc, filePath);
objectContext.SaveObject<Document>(doc);
}
FilePath — это путь к файлу, который прикрепляется к карточке документа Docsvision. В проекте есть xml файл конфигурации, в котором хранятся значения переменных, используемых в тестах: guid`ы карточек, поисковых запросов пути к файлам и т.д. Метод получает текущую сессию пользователя, проверяет, что она существует, создает новую карточку документа, заполняет в ней поля, добавляет файл с файловой системы и сохраняет карточку в базе.
Процесс тестирования
Запускаем нагрузку. Пока инициализируются счетчики производительности Windows на всех машинах, можно успеть налить чай.
Вначале обязательно проверяем, как система работает без нагрузки. Затем под небольшой. Это позволяет сразу увидеть, есть ли какие-то серьёзные проблемы в системе или на полигоне.
После запуска нагрузочных тестов, с помощью MS Visual Studio наблюдаем за временем выполнения каждого отдельного теста, нагрузкой на компьютерах, количеством тестов в секунду, количеством сессий пользователей, количеством успешныхпроваленных тестов, время выполнения каждого теста, среднее время выполнения каждого теста. Следим за счетчиками, ловим момент, когда, например, начинает загружаться процессор, память серверов. Смотрим на время, за которое выполняются тесты, это тоже важный параметр, поскольку даже если сервер обрабатывает все запросы, но делает это долго, пользователю это тоже не понравится, ему не важно, что происходит на сервере. Если в какой-то момент значения параметров становятся высокими, замечаем, какое количество виртуальных пользователей сейчас грузит наш сервер. Иногда имеет смысл в этот момент не останавливать нагрузку, а посмотреть, как система поведет себя дальше, до отказа.
Если всё в норме, ждём, пока все пользователи зайдут и система стабилизируется. При запуске большого числа пользователей мы иногда увеличиваем интенсивность действий пользователя, а не их количество, это позволяет уменьшить время выхода на стабильную нагрузку. После этого начинаем мерять показатели производительности: подключаемся с отдельной машины через клиент DV к серверу, смотрим, сколько по времени выполняются типичные действия пользователя Docsvision: открытие карточек, запуск Навигатора, отображение содержимого папок с большим количеством карточек (10000, 100000), открытие справочников и т.п. Полученные значения сохраняем в таблице и используем для сравнения со значениями с предыдущих замеров.
Результаты
Полученные данные анализируются вместе с начальником отдела тестирования и программистами. Узкие места более тщательно исследуются с помощью Fiddler`a, запросы в БД с помощью профайлера MS SQL Management Studio. Дальше результаты передаются системному архитектору и руководителю проекта для того, чтобы запланировать оптимизации на следующих итерациях разработки проекта.
Полученные данные анализируются вместе с начальником отдела тестирования обеспечения качества, директором по производству и программистами. Узкие места более тщательно исследуются с помощью Fiddler`a, запросы в БД с помощью профайлера MS SQL Management Studio. Дальше результаты передаются системному архитектору и руководителю проекта для того, чтобы запланировать оптимизации на следующих итерациях разработки проекта. На текущий момент становится понятно, что имеет смысл сравнивать не только результаты, полученные при измерении времени выполнения действий, выполняемых пользователем, и время выполнения серверных запросов, но и результаты счетчиков производительности Windows и сравнивать их между собой, чтобы видеть изменения во времени. Проблема в том, что на показатели влияет не только новые релизы DV, но и множество внешних параметров, как обновления Windows, переход на новую версию .Net и другие сторонние компоненты.
Почитать
Кроме ссылок в посте, вот ещё пара статей, которые помогли мне когда-то:
Длиннаяхорошая инструкция по поиску проблем взаимодействия между тестовыми агентами и контроллером: Troubleshooting Guide for Visual Studio Test Controller and Agent. В любой непонятной ситуации, прежде чем углубляться в эту статью, проверьте видят ли агент и контроллер друг друга :)- Deleting old load test results — скрипт для очистки базы с результатами нагрузочного тестирования. Может помочь, если после удаления результатов через интерфейс Visual Studio, ошибка «Load Test results repository is out of space…» остаётся.
- В посте описано тестирование с точки зрения использования Visual Studio, более подробно о методике нагрузочного тестирования самого Docsvision написано здесь.
Надеюсь, пост окажется для кого-нибудь полезным. Вопросы и замечания приветствуются. Интересно обменяться опытом и узнать, как организуется тестирование у вас.
Эта статья — совместное творчество Наталии Будённой и Ольги Трачук.
Автор: