Тестовые данные для стенда - генерация, пометка, чистка
Наполняем стенд правдоподобными данными: товары, заказы и пользователи с пометкой, защитой от запуска на боевом сайте и чисткой одной командой.
Что нужно знать заранее
Генератор данных - это скрипт, который умеет испортить боевой сайт. Первой строкой в нём стоит проверка, что запуск идёт на стенде, и без неё такой скрипт писать не стоит вовсе.
Сгенерированное помечают сразу при создании. Через неделю отличить тестовый товар от настоящего можно будет только по пометке, а не по названию или дате создания.
Запись элемента тянет за собой переиндексацию и пересчёт. На тысяче записей это превращается в часы ожидания, поэтому тяжёлые механизмы на время генерации отключают.
Шаги
- Поставить в начале скрипта проверку, что это стенд, а не боевой сайт.
- Выбрать пометку для сгенерированных записей и ставить её каждой из них.
- Отключить индексацию поиска и пересчёты на время массовой генерации.
- Создавать записи порциями, ведя журнал прохода по каждой порции.
- Написать чистку по пометке и проверить её до первой большой генерации.
Решение
Защищаемся от запуска на боевом сайте:
$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 и помечают так же, как и товары.
Смежное
-
Локальный стенд - оглавление подтемы
-
Стенд из копии боевого: подъём, обезличивание, отрезанные связи - другой способ наполнить стенд
-
Отладчик на стенде: подключение, точки останова, обмен и cron - разбор поведения на сгенерированных данных
-
Тесты для своего кода: что покрывать и как запускать - данные для автоматических проверок
-
Нагрузочное тестирование: сценарий, расчёт, чтение результатов - зачем нужен объём данных
-
Массовая правка товаров: обновление свойств скриптом - те же порции и журнал прохода
-
Настройки проекта: файл ядра, опции модуля, разные стенды - как отличают стенд от боевого
-
Окружение 1С-Битрикс - на чём поднимают такой стенд
-
Раздел Основы разработки
-
Разовый скрипт на боевом: запуск, защита, журнал, откат - защита скриптов от запуска не там