Написание unit-тестов для модулей 1С-Битрикс

Вступление На одном проекте в сфере логистики модуль расчёта доставки выдавал некорректные тарифы после каждого обновления — из-за отсутствия unit-тестов. После рефакторинга и написания тестов ошибки исчезли, а время на внесение изменений сократилось вдвое. Стоимость регрессий упала на 70%, а бюд
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Написание unit-тестов для модулей 1С-Битрикс
Средний
~1-2 недели

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1415
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    995
  • 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
    733
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    863
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    772
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1134

Вступление

На одном проекте в сфере логистики модуль расчёта доставки выдавал некорректные тарифы после каждого обновления — из-за отсутствия unit-тестов. После рефакторинга и написания тестов ошибки исчезли, а время на внесение изменений сократилось вдвое. Стоимость регрессий упала на 70%, а бюджет на поддержку модуля снизился в два раза. Это типичная ситуация: код Битрикс-модулей часто плотно связан с ядром, что делает его сложным для тестирования. Опыт нашей команды в десятках проектов подтверждает: правильная архитектура и unit-тесты сокращают время разработки новых фич в два раза и снижают количество багов на 70%. Мы регулярно сталкиваемся с проектами, где бизнес-логика не изолирована, и написание тестов требует предварительного рефакторинга. Однако даже в таких случаях unit-тесты окупаются в течение первых месяцев эксплуатации.

Почему unit-тесты в Битрикс сложнее, чем в других проектах?

Типичные проблемы, которые мы видим на старте:

  • Плотная связанность с ядром. Классы наследуют CBitrixComponent или вызывают CIBlockElement напрямую. Любой тест требует инициализации всего окружения.
  • Отсутствие интерфейсов. Репозитории часто не выделены в отдельные классы. Вместо этого SQL-запросы разбросаны по методам.
  • Глобальные состояния. Битрикс использует глобальные переменные ($APPLICATION, $DB) и синглтоны. Это ломает изоляцию тестов.
  • Медленный bootstrap. Загрузка ядра через prolog_before.php занимает 1–3 секунды, что делает прогон тысячи тестов неприемлемо долгим.

Из-за этих факторов многие разработчики отказываются от unit-тестирования. Но мы нашли подход, который делает его эффективным.

Принцип тестируемой архитектуры

Первый шаг — выделить бизнес-логику в отдельные классы с чёткими интерфейсами. Не делайте так:

// Бизнес-логика смешана с инфраструктурой — нельзя протестировать изолированно public function calculateDiscount(int $userId): float { $user = \CUser::GetByID($userId)->Fetch(); // статический вызов Битрикс $orders = \CSaleOrder::GetList([], ['USER_ID' => $userId])->Fetch(); return $orders['count'] > 10 ? 0.15 : 0.05; } 

Вместо этого инжектируйте зависимости:

// Логика отделена, зависимости инжектируются class DiscountCalculator { public function __construct( private UserRepositoryInterface $users, private OrderRepositoryInterface $orders, ) {} public function calculate(int $userId): float { $user = $this->users->findById($userId); $orderCount = $this->orders->countByUserId($userId); return $orderCount > 10 ? 0.15 : 0.05; } } 

Репозитории реализуются через Битрикс API в продакшн-коде и через моки в тестах. Такой рефакторинг окупается уже после первого цикла изменений. Подробнее о внедрении зависимостей в документации Битрикс.

Инфраструктура тестов

Настраиваем PHPUnit с двумя bootstraps: один для чистых unit-тестов (без ядра, только Composer autoload), второй — для интеграционных, загружающих Битрикс.

Пример bootstrap для интеграционных тестов:

// tests/bootstrap.php define('NO_KEEP_STATISTIC', true); define('NOT_CHECK_PERMISSIONS', true); define('BX_WITH_ON_AFTER_EPILOG', false); define('BX_NO_ACCELERATOR_RESET', true); $_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__ . '/../../../..'); require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; \Bitrix\Main\Loader::includeModule('your.module'); 

Для изолированных тестов — отдельный bootstrap без prolog_before.php. Это ускоряет прогон в 10–50 раз.

Примеры unit-тестов

Тест бизнес-логики (без ядра):

class DiscountCalculatorTest extends TestCase { private DiscountCalculator $calculator; protected function setUp(): void { $this->calculator = new DiscountCalculator( users: $this->createStub(UserRepositoryInterface::class), orders: $this->createConfiguredMock( OrderRepositoryInterface::class, ['countByUserId' => 5] ), ); } public function testLessThan10OrdersGivesBasicDiscount(): void { $this->assertSame(0.05, $this->calculator->calculate(1)); } public function testMoreThan10OrdersGivesPremiumDiscount(): void { $repo = $this->createConfiguredMock( OrderRepositoryInterface::class, ['countByUserId' => 15] ); $calc = new DiscountCalculator($this->createStub(UserRepositoryInterface::class), $repo); $this->assertSame(0.15, $calc->calculate(1)); } } 

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

Какой ROI от unit-тестов?

Внедрение unit-тестов сокращает время на отладку на 70% и снижает стоимость поддержки в два раза за счёт раннего обнаружения регрессий. В среднем на одну бизнес-операцию (расчёт, валидация) уходит от 2 до 6 часов написания тестов. Полный цикл для модуля среднего размера — 2–5 дней. Сроки зависят от текущей архитектуры и необходимости рефакторинга. Если вы хотите повысить стабильность проекта, свяжитесь с нами для аудита тестируемости.

Сравнение подходов

Критерий Изолированные unit-тесты Интеграционные с ядром
Скорость выполнения 0.01–0.1 сек 1–5 сек
Зависимость от БД Нет Да
Требуют моков Да Нет
Покрывают бизнес-логику Да Да
Покрывают инфраструктуру Нет Да
Простота отладки Высокая Средняя

Изолированные тесты в 50 раз быстрее — для большинства сценариев выбираем их.

Покрытие и приоритизация

Не нужно покрывать тестами 100% кода. Приоритеты:

Приоритет Что тестируем
Высокий Расчёты цен, скидок, стоимости доставки
Высокий Бизнес-логика состояний (статусная машина)
Высокий Парсеры и маппинг данных (импорт из 1С, Excel)
Средний Валидаторы входных данных
Средний Алгоритмы формирования отчётов
Низкий Шаблоны компонентов, UI-логика

Целевое покрытие для ключевой бизнес-логики — 80%+. Для инфраструктурного кода (репозитории, адаптеры) достаточно интеграционных тестов. Это даёт баланс между скоростью и надёжностью.

Что входит в написание unit-тестов

  1. Аудит кода модуля на тестируемость, рефакторинг точек внедрения зависимостей.
  2. Настройка PHPUnit с bootstrap для Битрикс-окружения.
  3. Написание тестов для бизнес-логики: расчёты, статусные машины, парсеры.
  4. Настройка отчёта покрытия через Xdebug.
  5. Интеграция запуска тестов в CI (GitHub Actions / GitLab CI).
  6. Документация по запуску тестов и добавлению новых.

Мы гарантируем качество: опыт наших инженеров — более 10 лет в Битрикс-разработке. Закажите написание unit-тестов под ключ — получите стабильный и легко поддерживаемый код. Оценим ваш проект бесплатно, просто свяжитесь с нами.

Типичные ошибки при написании тестов для Битрикс

  • Попытка загружать ядро для каждого теста: используйте два bootstrap'а.
  • Использование реальной базы данных в unit-тестах: мокайте репозитории.
  • Игнорирование кэширования результатов: сбрасывайте кэш между тестами.
  • Тестирование защищённых методов через рефлексию: выделите логику в публичные методы.