Атака Неклонов, Или Генерация И Анализ Тестовых Данных Под Нагрузку. Часть 1

Как добиться необходимого контроля, удобства и даже скорости при подготовке тестовых данных для микросервисов и тестов производительности? Когда лучше не создавать файлы XML и JSON с помощью конкатенации строк? Зачем анализировать статистику по SQL-запросам? Меня зовут Вячеслав Смирнов, я ускоряю ДБО для юридических лиц, а также поддерживаю чат. Контроль качества: нагрузка и производительность в Telegram, где сообщество инженеров по тестированию производительности обсуждает нагрузочное тестирование.

Статья получилась длинной, поэтому сегодня я расскажу о подготовке тестовых данных для тестирования производительности и о том, как подготовить эти данные с помощью SQL, Pandas и Java. Давайте поговорим об анализе метрик и журналов с точки зрения данных и использовании InfluxDB, Grafana и других инструментов.

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

В следующих частях я перейду к формированию и анализу тестовых данных под нагрузку.



Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

Вы можете посмотреть видео моего выступления на эту тему Здесь , и согласно этому связь - презентация.

Для новых микросервисов неоткуда взять тестовые данные.

У нас есть только микросервис и его пустая база данных.

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

И нам нужно смоделировать именно такую большую систему.

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

Как правило, файлы JSON отправляются через API, по крайней мере в тех банковских системах, с которыми я имел дело.

Со стороны базы данных генерация данных происходит намного быстрее.

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

В этом случае сервер базы данных практически не напрягается, ведь мы сгенерировали данные, поместили их в CSV-таблицы и загрузили прямо в таблицу SQL-запросом на импорт CSV-файла:

   

COPY table_name [ ( column_name [, .

])] FROM ‘filename’ [[WITH] [DELIMITER [AS] ‘delimiter_character’] [NULL [AS] ‘null_string’] [CSV [HEADER] [QUOTE [AS] ‘quote_character’] [ESCAPE [AS] 'escape_character’] [FORCE NOT NULL column_name [, .

]]]]

Но есть нюанс.

Если вы генерируете, например, 500 ГБ данных, вам также придется создать 500 ГБ файлов CSV. Обычно ни у кого нет свободных 500 ГБ.

Поэтому я предпочитаю другой путь — использование хранимых процедур («хранимых»).

В этом случае сервер базы данных как генерирует, так и получает данные.

Нагрузка на него больше, но потребление дискового пространства меньше.

Если вам нужны конкретные данные, которые невозможно сохранить, это можно сделать только на Java или Python, например, хэши паролей.

Я генерирую их, сохраняю в CSV и уже готовые скачиваю.

А самые сложные критичные данные, которых не нужно много или если можно подождать, я генерирую через API.

Клонировать или обезличить невозможно или сложно.

Если сервис не новый, то вроде бы можно скопировать правильные данные, то есть сделать клоны данных.

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

Потому что есть закон о персональных данных.

Требуется обезличивание данных.

Исходные данные изменяются и передаются из одной базы данных в другую.

Обезличивание часто выполняется на уровне SQL-запроса.

А данные на уровне SQL просто проверяются на целостность.

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

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

Но если делать это только на уровне SQL, то очень легко допустить ошибки.

Деперсонализация часто приводит к этому:

Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

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

Все это привело к тому, что правильные данные стали неверными: ФИО больше не проходило проверку ФИО, а номер ИНН не проходил проверку контрольной суммы.

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

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

А в автотестах и нагрузочных тестах мы получаем постоянный процент ошибок:

Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

Часть тестов, связанная с неверными тестовыми данными, всегда завершается неудачно.

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



Генерация данных без Random

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

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

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

Если у нас есть компания, то у нее должны быть клиенты, у которых должны быть документы.

Если идентификаторы разные, компания 1 попытается получить документы компании 777, но ничего не получит, поскольку данные не связаны.

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

Но не только генерация данных для микросервисов имеет свои особенности.



Подготовка данных для тестов производительности

Нагрузочные тесты должны быть атомарными.

Давайте рассмотрим атомарность на примере интерфейса входа в банк.

Вход с правильным паролем есть — это один тестовый пример.



Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

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

Сброс пароля — третий тестовый пример.

При использовании этих случаев лучше разделить для них тестовые данные.

Например, по домену электронной почты, чтобы логины заканчивались на разных доменах (@ok.ru, @fail.ru, @pass.ru), чтобы они были разными и не пересекались в разных действиях.

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

Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

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

Это важная часть методологии тестирования.



Данные должны быть одноразовыми

Второй важный момент в нагрузке, как и в автоматизации, — данные должны быть одноразовыми.

Например, у вас есть вход по логину и паролю.

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

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

Невозможно изменить пароль дважды, потому что я меняю пароль 1 на пароль 2, и снова изменить пароль 1 на пароль 2 уже невозможно.

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

В противном случае вы не сможете протестировать следующие сценарии:

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

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



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

Часто при загрузке используется распределенный запуск нагрузки, когда есть микросервис, мы применили код к трем Linux-агентам и с этих трех станций нагрузка подается на одну систему.

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

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

Распространенными системами являются сервер виртуальных таблиц (VTS) от HP LoadRunner и простой сервер таблиц от Apache.JMeter, которые работают через HTTP. Некоторые люди используют AMQP или Redis. Я рекомендую разные файлы CSV для разных агентов.

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

Я гарантирую, что первый агент использует первый CSV-файл, второй — второй и третий — третий, либо задаю это в свойстве в файле конфигурации, либо другим способом.

Например, я проверяю, чтобы имя файла соответствовало имени агента.

Это возможно, если ваши агенты постоянны и не создаются в Kubernetes для каждого теста.

Чаще всего агенты нагрузки делают постоянными.



Часто проводите тесты, быстро готовьте данные

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

Например, мы используем 100 тысяч объектов и миллион объектов в базе для CSV-файлов, но за час тестирования изменилось всего 10 тысяч объектов — 1% объектов в базе.

После каждого 1% изменения мы не будем перегенерировать или восстанавливать всю базу данных.

Существуют разные подходы:

Атака неклонов, или Генерация и анализ тестовых данных под нагрузку.
</p><p>
 Часть 1

Генерация данных — самый длительный подход. Я условно указал, что это неделя работы, но бывает разнится.

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

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

Это сэкономит вам время, и вы сможете восстанавливать данные из резервной копии, например, только раз в месяц.

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

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

И самый быстрый способ — обновить измененные записи, потому что журнал транзакций сильно не вырастет, вы измените только 1% данных.

Я стремлюсь использовать именно такой подход, и вам тоже советую – он самый простой.

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

Конференция по автоматизации тестирования Конференция TestDriven 2022 пройдет в Москве 28-29 апреля 2022 г.

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

Помимо хардкора про автоматизацию и разработку в тестировании, будут и вещи полезные в повседневной работе.

Принятые отчеты можно просмотреть Здесь , и купить билет - Здесь .

Теги: #Высокая производительность #qa #java #тестирование ИТ-систем #sql #qa тестирование #influxdb #производительность #pandas #тестовые данные #нагрузочное тестирование #нагрузочные тесты
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.