Написание интеграционных тестов для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Написание интеграционных тестов для 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Написание интеграционных тестов для 1С-Битрикс

Вы деплоите обновление, и через час обнаруживаете, что импорт из 1С перестал создавать новые товары — изменилась сигнатура метода в модуле catalog, а код интеграции не был обновлён. Интеграционные тесты решают именно эту проблему: они проверяют, что ваш код корректно взаимодействует с ядром Битрикс, БД и внешними системами. Не юнит-тесты в вакууме, а реальные сценарии с реальным ядром.

Чем интеграционные тесты отличаются от юнит-тестов в контексте Битрикс

Юнит-тесты Битрикс-проекта бесполезны без моков половины ядра. Класс, вызывающий CIBlockElement::GetList(), зависит от инфоблоков, БД, кэша, прав доступа. Мокировать всё это — писать второй Битрикс. Интеграционные тесты загружают реальное ядро, работают с реальной (тестовой) БД и проверяют полный цикл.

Типичные сценарии:

  • Создание заказа через CSaleOrder::Add() / \Bitrix\Sale\Order::create() — проверка, что все обработчики событий отрабатывают, скидки применяются, статус корректен
  • Импорт товаров из XML — проверка маппинга полей, создания разделов, обновления цен
  • Формирование выгрузки для 1С — проверка структуры XML, корректности данных
  • Обработка webhook от платёжной системы — проверка смены статуса заказа

Настройка тестового окружения

PHPUnit + ядро Битрикс. Битрикс не поставляется с тестовой инфраструктурой, её нужно настроить вручную.

Файл bootstrap.php для PHPUnit:

$_SERVER['DOCUMENT_ROOT'] = '/path/to/site';
$_SERVER['HTTP_HOST'] = 'test.local';
$_SERVER['SERVER_NAME'] = 'test.local';
$GLOBALS['DBType'] = 'mysql'; // или pgsql

define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('BX_NO_ACCELERATOR_RESET', true);
define('STOP_STATISTICS', true);

require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

Константы NO_KEEP_STATISTIC и STOP_STATISTICS отключают запись статистики, NOT_CHECK_PERMISSIONS — проверку прав (иначе тесты будут зависеть от текущего пользователя).

Тестовая БД. Два подхода:

  1. Отдельная БД — копия продакшн-схемы без данных. Безопасно, но требует поддержки синхронизации схемы.
  2. Транзакции — каждый тест оборачивается в транзакцию, которая откатывается в tearDown(). Быстро, но не работает для тестов, которые сами используют транзакции (вложенные транзакции в MySQL ведут себя неочевидно).

Рекомендуемый подход для Битрикс — транзакции с фоллбэком на ручную очистку:

protected function setUp(): void
{
    \Bitrix\Main\Application::getConnection()->startTransaction();
}

protected function tearDown(): void
{
    \Bitrix\Main\Application::getConnection()->rollbackTransaction();
}

Структура тестов

Размещайте тесты в /local/tests/ с зеркальной структурой:

/local/tests/
  Integration/
    Catalog/
      ImportTest.php      → тесты импорта товаров
      PriceCalculationTest.php
    Sale/
      OrderCreationTest.php
      DiscountTest.php
    Exchange/
      OneCExportTest.php
  bootstrap.php
  phpunit.xml

phpunit.xml:

<phpunit bootstrap="bootstrap.php">
    <testsuites>
        <testsuite name="Integration">
            <directory>Integration</directory>
        </testsuite>
    </testsuites>
</phpunit>

Написание тестов: паттерны для Битрикс

Тест создания заказа:

public function testOrderCreationWithDiscount(): void
{
    // Arrange: создаём тестовый товар и скидку
    $productId = $this->createTestProduct('TEST-001', 1000);
    $discountId = $this->createTestDiscount(10); // 10%

    // Act: создаём заказ
    $order = \Bitrix\Sale\Order::create('s1', 1);
    $basket = \Bitrix\Sale\Basket::create('s1');
    $item = $basket->createItem('catalog', $productId);
    $item->setFields(['QUANTITY' => 1, 'CURRENCY' => 'RUB', 'PRODUCT_PROVIDER_CLASS' => '\CCatalogProductProvider']);
    $order->setBasket($basket);
    $order->doFinalAction(true);
    $result = $order->save();

    // Assert
    $this->assertTrue($result->isSuccess());
    $this->assertEquals(900, $order->getPrice()); // 1000 - 10%
}

Тест импорта XML:

Не вызывайте CIBlockCMLImport напрямую — он тяжёлый и плохо контролируемый. Тестируйте ваш код-обёртку, который вызывает API Битрикс:

public function testProductImportCreatesElement(): void
{
    $importer = new \Project\Import\ProductImporter(CATALOG_IBLOCK_ID);
    $result = $importer->import([
        'XML_ID' => 'TEST-IMPORT-001',
        'NAME' => 'Тестовый товар',
        'PRICE' => 500,
    ]);

    $this->assertTrue($result->isSuccess());

    $element = \CIBlockElement::GetList(
        [],
        ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'XML_ID' => 'TEST-IMPORT-001'],
        false, false, ['ID', 'NAME']
    )->Fetch();

    $this->assertNotFalse($element);
    $this->assertEquals('Тестовый товар', $element['NAME']);
}

Обработка событий в тестах

Обработчики событий Битрикс (OnBeforeIBlockElementAdd, OnSaleOrderBefore, и т.д.) — источник неожиданного поведения в тестах. Обработчик, зарегистрированный в init.php, срабатывает и в тестовом окружении.

Два подхода:

  1. Принять как данность — тест проверяет систему целиком, включая обработчики. Это правильнее с точки зрения интеграционного тестирования.
  2. Временно отключитьRemoveEventHandler() в setUp(), восстановить в tearDown(). Используйте, когда обработчик вызывает внешний сервис (отправка email, запрос к API).

Что не стоит тестировать интеграционно

  • Вёрстку и визуальное отображение — это задача для E2E-тестов (Playwright, Selenium)
  • Чистую бизнес-логику без зависимостей от Битрикс — это юнит-тесты
  • Производительность — интеграционные тесты медленные по определению, для бенчмарков используйте отдельный фреймворк

Сроки написания тестов

Покрытие Объём Срок
Критический путь (оформление заказа, импорт) 15-25 тестов 3-5 дней
Основная функциональность 50-80 тестов 1-2 недели
Расширенное покрытие (edge cases, ошибки) 100+ тестов 3-4 недели

Начинайте с тестов на те места, где чаще всего ломается. Обычно это импорт/экспорт 1С и расчёт цен с учётом скидок.