Перейти к содержимому

Тестовые данные для стенда - генерация, пометка, чистка

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

Что нужно знать заранее

Генератор данных - это скрипт, который умеет испортить боевой сайт. Первой строкой в нём стоит проверка, что запуск идёт на стенде, и без неё такой скрипт писать не стоит вовсе.

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

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

Шаги

  1. Поставить в начале скрипта проверку, что это стенд, а не боевой сайт.
  2. Выбрать пометку для сгенерированных записей и ставить её каждой из них.
  3. Отключить индексацию поиска и пересчёты на время массовой генерации.
  4. Создавать записи порциями, ведя журнал прохода по каждой порции.
  5. Написать чистку по пометке и проверить её до первой большой генерации.

Решение

Защищаемся от запуска на боевом сайте:

$host = \Bitrix\Main\Context::getCurrent()->getServer()->getHttpHost() ?: gethostname();
if (!preg_match('/(dev|test|local)/i', (string)$host)) {
die("генератор запускается только на стенде\n"); // боевой сайт не трогаем
}

Проверка по имени узла - минимум, который спасает от катастрофы. Надёжнее опираться на явную настройку стенда в файле проекта, а имя узла держать вторым рубежом.

Генерируем товары порциями:

$el = new \CIBlockElement();
foreach (range(1, 5000) as $i) {
$el->Add(['IBLOCK_ID' => $iblockId, 'NAME' => 'Тестовый товар ' . $i,
'XML_ID' => 'TESTDATA_' . $i, // пометка для будущей чистки
'CODE' => 'testdata-' . $i,
'PROPERTY_VALUES' => ['ARTICLE' => 'T-' . $i]], false, false, false);
if ($i % 500 === 0) { echo "создано $i\n"; } // журнал прохода по порциям
}

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

Отключаем тяжёлое на время генерации:

\CIBlock::DisableTagCache($iblockId); // не сбрасывать тегированный кэш
$el->Add([... 'PROPERTY_VALUES' => $props], false, false, false);
// четвёртый аргумент выключает пересчёт поискового индекса на каждой записи
\CIBlock::EnableTagCache($iblockId);

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

Создаём заказы через API продаж:

$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$basket = \Bitrix\Sale\Basket::create(SITE_ID);
$item = $basket->createItem('catalog', $productId);
$item->setFields(['QUANTITY' => 2, 'CURRENCY' => 'RUB', 'LID' => SITE_ID,
'PRODUCT_PROVIDER_CLASS' => \CCatalogProductProvider::class]);
$order->setBasket($basket);
$order->setField('XML_ID', 'TESTDATA_' . $i); // та же пометка на заказе
$order->save();

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

Чистим сгенерированное по пометке:

$rs = \CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'XML_ID' => 'TESTDATA_%'],
false, ['nTopCount' => 500], ['ID']);
while ($row = $rs->Fetch()) { \CIBlockElement::Delete($row['ID']); }
// запускают несколько раз подряд: за проход уходит одна порция записей

Типичные проблемы

Тестовые товары появились на боевом сайте.

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

Сгенерированное невозможно отличить от настоящего.

Записи создавались без пометки во внешнем коде или в служебном свойстве. Пометку ставят при создании, а не пытаются угадать её потом по дате.

Генерация тысячи товаров идёт несколько часов.

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

Со стенда ушли письма реальным покупателям.

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

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

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

Частые вопросы

Чем плоха копия боевой базы вместо генерации?

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

Сколько данных генерировать?

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

Как генерировать картинки товаров?

Класть один файл-заглушку и ссылаться на него из всех записей. Тысяча одинаковых картинок занимает место и ничего не проверяет.

Можно ли удалить тестовые данные запросом к базе?

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

Нужны ли тестовые заказы?

Нужны, если проверяется личный кабинет, отчёты или обмен с учётной системой. Их создают штатным API и помечают так же, как и товары.

Смежное

Первоисточник