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

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Написання інтеграційних тестів для 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

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

Ви деплоїте оновлення, та через годину виявляєте, що імпорт з 1С перестав створювати нові товари — змінилася сигнатура методу в модулі catalog, а код інтеграції не був оновлений. Інтеграційні тести вирішують саме цю проблему: вони перевіряють, що ваш код коректно взаємодіє з ядром Бітрікса, БД та зовнішніми системами. Не юнит-тести у вакуумі, а реальні сценарії з реальним ядром.

Чим інтеграційні тести відрізняються від юнит-тестів у контексті Бітрікса

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

Типові сценарії:

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

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

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С та розрахунок цін з урахуванням скидок.