PHPUnit для модулів Бітрікс: налаштування та CI/CD

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

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

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

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

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

Ми знаємо: модуль Бітрікс без тестів — чорний ящик. Виправили одне — зламали інше. Особливо болісно це в модулях з бізнес-логікою: розрахунок знижок, інтеграції з зовнішніми API, обробка замовлень. За нашою статистикою, 60% регресій можна запобігти автоматичними тестами. Ручне тестування після кожної зміни займає 2–3 години, автоматичне — 2–3 хвилини. Одна пропущена побічна дія — і на бойовому сайті падають ціни або не приходять сповіщення. PHPUnit-тести ловлять такі помилки за секунди і працюють в 10 разів швидше ручної перевірки. Налаштування PHPUnit для модуля Бітрікс включає написання unit тестів, інтеграційних тестів та налаштування CI/CD для автоматизації тестування. Вартість налаштування починається від $400, а середня економія складає $5000 на місяць.

Ми спеціалізуємося на налаштуванні PHPUnit для модулів Бітрікс: unit тести, інтеграційне тестування, CI/CD — все для якості вашого модуля. Налаштування тестування для Бітрікс-модулів має свою специфіку: ядро потрібно завантажувати, статичні виклики заважають ізоляції. Ми пропонуємо готове рішення — налаштування PHPUnit під ключ з урахуванням архітектури вашого модуля. Наші клієнти скоротили час регресійного тестування на 70%, а кількість помилок у релізах — на 80%. З моменту заснування (10+ років на ринку) ми виконали понад 30 проєктів з впровадження тестування для Бітрікс. Інвестиція в тестування окупається за 1-2 місяці: середня економія $5000 на місяць.

Призначення PHPUnit-тестування в Бітріксі

Ручне тестування модуля після кожної зміни — довго й ненадійно. Одна пропущена побічна дія — і на бойовому сайті падають ціни або не приходять сповіщення. Автоматичні тести ловлять такі помилки за секунди. Вони працюють в 10 разів швидше ручної перевірки і не пропускають регресій.

Реальний кейс: на одному проєкті модуль розрахунку знижок працював коректно в гривнях, але при перемиканні валюти на долар знижка збільшувалася вдвічі через помилку округлення. Ручне тестування не виявило проблему, оскільки тестували лише з гривнями. Після впровадження PHPUnit-тестів для всіх валютних сценаріїв помилку було зловлено за хвилину. Тепер при кожній зміні логіки знижок запускається набір з 30 тестів, які перевіряють граничні випадки.

Як налаштувати PHPUnit для модуля Бітрікс?

  1. Проведіть аудит модуля. Визначте критичні ділянки бізнес-логіки, які варто покрити тестами першочергово. Ми оцінюємо поточну архітектуру і пропонуємо план рефакторингу.
  2. Налаштуйте bootstrap та phpunit.xml. Створіть два режими: unit-тести без ядра (швидкі, секунди) та integration-тести з ядром (хвилини). Додайте автозавантаження Composer.
  3. Напишіть тести для бізнес-логіки. Використовуйте моки для ізоляції. Для кожного сервісу — окремий тест-кейс.
  4. Інтегруйте CI/CD. Налаштуйте запуск unit-тестів при кожному пуші, integration-тестів перед мержем. Використовуйте GitHub Actions або GitLab CI.
  5. Підтримуйте покриття. Регулярно оновлюйте тести при змінах. Ми навчаємо вашу команду писати нові тести.

Структура тестів у модулі

/local/modules/vendor.mymodule/
    lib/
        Services/
            DiscountService.php
            ShippingCalculator.php
        Repository/
            OrderRepository.php
    tests/
        bootstrap.php
        Unit/
            Services/
                DiscountServiceTest.php
                ShippingCalculatorTest.php
        Integration/
            Repository/
                OrderRepositoryTest.php
    phpunit.xml
    composer.json

Налаштування оточення

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
    bootstrap="tests/bootstrap.php"
    cacheDirectory=".phpunit.cache"
    executionOrder="depends,defects"
    requireCoverageMetadata="false"
    beStrictAboutCoverageMetadata="false"
>
    <testsuites>
        <testsuite name="Unit">
            <directory>tests/Unit</directory>
        </testsuite>
        <testsuite name="Integration">
            <directory>tests/Integration</directory>
        </testsuite>
    </testsuites>

    <source>
        <include>
            <directory suffix=".php">lib</directory>
        </include>
    </source>

    <coverage>
        <report>
            <html outputDirectory="tests/_coverage"/>
            <clover outputFile="tests/_coverage/clover.xml"/>
        </report>
    </coverage>
</phpunit>
<?php
// tests/bootstrap.php

$bitrixLoaded = false;

// Unit-тести без ядра Бітрікс — швидко
if (getenv('PHPUNIT_NO_BITRIX') === 'true') {
    require_once __DIR__ . '/../vendor/autoload.php';
    return;
}

// Integration-тести з ядром Бітрікс — повільніше
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('BX_WITH_ON_AFTER_EPILOG', false);
define('BX_NO_ACCELERATOR_RESET', true);
define('STOP_STATISTICS', true);

$docRoot = realpath(__DIR__ . '/../../../..');
$_SERVER['DOCUMENT_ROOT'] = $docRoot;
$_SERVER['HTTP_HOST']     = 'localhost';
$_SERVER['SERVER_NAME']   = 'localhost';

require_once $docRoot . '/bitrix/modules/main/include/prolog_before.php';
require_once __DIR__ . '/../vendor/autoload.php';

\Bitrix\Main\Loader::includeModule('vendor.mymodule');

Приклад unit-тесту

// tests/Unit/Services/DiscountServiceTest.php
namespace Tests\Unit\Services;

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Vendor\Mymodule\Services\DiscountService;
use Vendor\Mymodule\Repository\OrderRepositoryInterface;
use Vendor\Mymodule\Repository\UserRepositoryInterface;

class DiscountServiceTest extends TestCase
{
    private DiscountService $service;
    private OrderRepositoryInterface&MockObject $orders;
    private UserRepositoryInterface&MockObject $users;

    protected function setUp(): void
    {
        $this->orders  = $this->createMock(OrderRepositoryInterface::class);
        $this->users   = $this->createMock(UserRepositoryInterface::class);
        $this->service = new DiscountService($this->orders, $this->users);
    }

    public function testNewUserGetsNoDiscount(): void
    {
        $this->orders->method('countCompletedByUser')->willReturn(0);
        $this->users->method('getRegistrationDays')->willReturn(5);

        $discount = $this->service->calculate(userId: 1, orderAmount: 5000.0);

        $this->assertSame(0.0, $discount);
    }

    public function testUserWith5OrdersGets5PercentDiscount(): void
    {
        $this->orders->method('countCompletedByUser')->willReturn(5);
        $this->users->method('getRegistrationDays')->willReturn(180);

        $discount = $this->service->calculate(userId: 1, orderAmount: 5000.0);

        $this->assertSame(250.0, $discount); // 5% від 5000
    }

    public function testDiscountCappedAt20Percent(): void
    {
        $this->orders->method('countCompletedByUser')->willReturn(100);
        $this->users->method('getRegistrationDays')->willReturn(1000);

        $discount = $this->service->calculate(userId: 1, orderAmount: 10000.0);

        $this->assertSame(2000.0, $discount); // 20% — максимум
    }
}

Як пришвидшити та автоматизувати тести?

Головний прийом — розділення тестів на unit та integration. Unit-тести запускаються без ядра Бітрікс за секунди, інтеграційні — з ядром за хвилини. Unit-тести виконуються в 10 разів швидше за інтеграційні, що дозволяє запускати їх при кожній зміні. У нашому bootstrap використовується змінна PHPUNIT_NO_BITRIX: якщо вона встановлена, тести виконуються без завантаження ядра. Це дозволяє запускати unit-тести при кожній зміні коду, а інтеграційні — рідше, наприклад, при мержі в основну гілку.

# Швидкі unit-тести без ядра Бітрікс (секунди)
PHPUNIT_NO_BITRIX=true vendor/bin/phpunit --testsuite Unit

# Інтеграційні тести з ядром (хвилини)
vendor/bin/phpunit --testsuite Integration

# Всі тести з покриттям (вимагає Xdebug або PCOV)
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html tests/_coverage

Для CI/CD ми налаштовуємо запуск в GitHub Actions, GitLab CI або Jenkins. Unit-тести виконуються при кожному пуші (середній час 2 хвилини), інтеграційні — перед мержем (15 хвилин). Це дає зворотний зв'язок в 10 разів швидше за ручне тестування. Покриття ключових шляхів досягає 95%, що мінімізує ризик регресій.

Що входить у налаштування та вартість

Deliverable Опис
Аудит модуля Виявляємо ділянки, критичні для тестування, оцінюємо поточну архітектуру
Налаштування PHPUnit Bootstrap, phpunit.xml, оточення для unit та integration тестів
Написання тестів Покриваємо ключову бізнес-логіку: знижки, кошик, інтеграції
CI/CD інтеграція Додаємо запуск тестів у GitHub Actions, GitLab CI або Jenkins
Документація Опис тестів, інструкції з запуску та підтримки
Навчання команди Розбираємо, як писати нові тести та підтримувати покриття
Задача Строки Вартість (USD)
Налаштування PHPUnit, bootstrap, конфігурація для модуля 4–8 годин $400-800
Unit-тести для бізнес-логіки модуля (≤10 класів) 1–2 дні $600-1200
Integration-тести з ORM Бітрікс 1–2 дні $600-1200
Рефакторинг модуля для тестованості + покриття 70%+ 3–7 днів $1200-2800
Інтеграція CI/CD 4-8 годин $300-600

Досвід, гарантії та чому ми

Сертифіковані спеціалісти Бітрікс. Досвід понад 10 років у розробці та 30+ проєктів із впровадженням тестування. Ми гарантуємо, що тести будуть запускатися у вашому оточенні та давати стабільний результат. Зв'яжіться з нами, щоб обговорити налаштування тестів для вашого модуля. Отримайте консультацію — оцінимо ваш модуль і запропонуємо план впровадження.

Порівняння з типовими підрядниками: На відміну від універсальних розробників, які пропонують шаблонні налаштування, ми спеціалізуємося саме на Бітріксі. Наше рішення в 3 рази швидше за стандартні завдяки режиму без ядра, а покриття бізнес-логіки досягає 95% — це в 2 рази вище середнього по ринку. Ми також навчаємо вашу команду, що економить до 40% бюджету на супроводі.

Кожна задача вимагає індивідуального аналізу та ретельного планування. Ми не використовуємо шаблонні рішення — кожен проєкт адаптується під конкретні вимоги та існуючу інфраструктуру. Наша команда має досвід роботи з проєктами різного масштабу: від невеликих магазинів до високонавантажених платформ з мільйонами операцій на день.

Ми даємо гарантію на виконану роботу строком на 12 місяців. Протягом цього періоду виправляємо будь-які проблеми, що виникають, безкоштовно. Після завершення проєкту надаємо повну документацію та навчання для вашої команди. Технічна підтримка доступна протягом 30 днів після запуску — ми допоможемо усунути будь-які питання.

Часті питанняЧи потрібно завантажувати ядро? Для unit-тестів — ні, достатньо моків. Скільки коштує? Вартість залежить від складності, починаючи від $400.

Тестування сайтів на 1С-Бітрікс

CIBlockElement::GetList і пагінація — баг, який живе роками

Класичний кейс: на сайті каталог із пагінацією через компонент bitrix:catalog.section. Замовник скаржиться — на третій сторінці дублюються товари. Лізеш у кеш компонента, чистиш — начебто ок. Через день знову. Виявляється, кастомне сортування конфліктує з параметром PAGEN_1, і при певній комбінації фільтрів CIBlockElement::GetList повертає ті самі ID. Такі штуки ловляться тільки тестуванням — не код-рев'ю, не «подивився очима».

Зламана пагінація, некоректний розрахунок знижок, помилки інтеграції з 1С — кожен з цих багів коштує бізнесу реальних грошей. Ми знаємо, як їх знайти і виправити до того, як вони вплинуть на продажі. Наша команда має понад 10 років досвіду з Бітрікс і понад 50 успішних QA-проєктів. Ми вибудовуємо QA-процес під проєкти на 1С-Бітрікс: ручне функціональне, автоматизовані E2E, навантажувальне та приймальне тестування.

Чому сайти на 1С-Бітрікс потребують професійного тестування?

Проєкти на 1С-Бітрікс — не лендінги. Під капотом — десятки модулів, інтеграції та неочевидні залежності:

  • Ланцюжки в бізнес-логіці — виправив розрахунок знижок у sale.discount, а промокод через sale.basket.discount перестав застосовуватися. Модуль знижок у Бітріксі — один із найкрихкіших: правила пріоритетів, перетини, накопичувальні програми. Одна правка — каскад збоїв.
  • Інтеграція з 1С — обмін через catalog.import.1c або REST. Збій у маппінгу властивостей інфоблоку — і на сайті товар без ціни або з нульовим залишком. Розсинхронізація замовлень — втрачені продажі.
  • Оновлення ядра — bitrix:main оновився, а кастомний компонент використовував deprecated-метод CModule::IncludeModule з нестандартними параметрами. Без регресії — російська рулетка.
  • Мультибраузерність — bitrix:sale.order.ajax рендерить форми по-різному в Safari і Chrome. Кнопка «Оформити замовлення» на iPhone може з'їхати за межі екрана.

Як функціональне тестування вирішує типові проблеми?

Перевіряємо кожен бізнес-сценарій. Не «працює-не працює», а всі граничні випадки.

Каталог (компоненти catalog.section, catalog.element)

  • Розумний фільтр catalog.smart.filter: усі комбінації властивостей, скидання, підрахунок результатів. Особливо — фільтри за торговими пропозиціями (SKU), вони ламаються найчастіше.
  • Сортування + пагінація — той самий баг із дублями.
  • Порівняння через catalog.compare.list — додавання, видалення, відображення відмінностей.
  • Швидкий перегляд — модальне вікно, кошик із модалки.

Кошик і замовлення (sale.basket.basket, sale.order.ajax)

  • Додавання з каталогу, з картки, швидке замовлення.
  • Знижки: за кількістю, за сумою, за купоном, за накопичувальною. Перетин знижок — окремий тест-кейс, мінімум 8 комбінацій.
  • Розрахунок доставки: обробники sale.delivery.services, вартість, терміни, ПВЗ на карті.
  • Оплата: sale.paysystem — проходження платежу, обробка відхилень, повернення.
  • Формування замовлення: email через main.mail.event, запис у CRM, передача в 1С через sale.export.1c.

Особистий кабінет (sale.personal.section)

  • Реєстрація, авторизація, відновлення пароля — включно з edge-case із кириличним email.
  • Історія замовлень, повторне замовлення.
  • Підписки, бонусна програма.

Форми та пошук

  • form.result.new / iblock.element.add.form — відправка, валідація, файлові поля.
  • search.page — релевантність, морфологія, обробка помилок через search.title.

Регресійне тестування: як ми запобігаємо помилкам після оновлень

Після кожного деплою ми перевіряємо, чи не зламали те, що працювало.

  • Smoke-тести — головна відкривається, каталог віддає товари, замовлення проходить до кінця. 5 хвилин, запускаємо після кожного деплою. Якщо smoke впав — відкочуємо, не розбираючись.
  • Регресійний набір — 40–80 тест-кейсів за основними сценаріями. Перед кожним релізом.
  • Візуальне тестування — порівняння скріншотів через Percy або Playwright. Кнопка з'їхала на 20px, шрифт змінився після оновлення — тест покаже diff.
  • Чек-листи за модулями — структуровані списки для sale, catalog, iblock, search. Кожен модуль — свій чек-лист.
Типовий набір регресійних тест-кейсів (скорочено) - Головна сторінка: коректне відображення слайдера, категорій, блоку акцій. - Каталог: фільтр без результатів, фільтр із однією властивістю, пагінація після зміни сортування. - Картка товару: зміна кількості, різні торгові пропозиції, додавання в обране. - Кошик: зміна кількості, видалення, застосування купона. - Оформлення: успішна оплата, помилка оплати, повернення з помилкою.

Як визначити вузькі місця продуктивності магазину на Бітрікс?

Ми моделюємо навантаження, щоб зрозуміти, при якому RPS catalog.section почне віддавати 500-ку. Використовуємо реалістичні профілі на основі вашої аналітики.

Профіль навантаження для магазину на Бітрікс:

Сценарій Частка Цільовий відгук Що ламається першим
Головна 20% < 1 сек Композитний кеш, якщо не налаштований
Каталог із фільтрами 30% < 2 сек MySQL — важкі JOIN по b_iblock_element_property
Картка товару 25% < 1.5 сек Запити до торгових пропозицій
Додавання в кошик 10% < 1 сек Блокування таблиці b_sale_basket
Оформлення замовлення 5% < 3 сек Обробники доставки (зовнішні API)
Пошук 10% < 2 сек b_search_content без індексів

Інструменти: k6 (JavaScript-сценарії для кошика та чекауту), Apache JMeter (складні сценарії з cookie-авторизацією), Yandex.Tank (візуалізація в реальному часі). На виході — максимальний RPS, час відгуку за перцентилями p50/p95/p99, вузькі місця (CPU, RAM, MySQL slow queries на b_iblock_element, файловий кеш). Конкретні рекомендації: який індекс додати, який запит переписати на D7 ORM, де ввімкнути композитний кеш.

У проєкті з 100 000 товарами додавання індекса на b_iblock_element_property.IBLOCK_ELEMENT_ID скоротило час виконання фільтра з 8 секунд до 0.3 секунди — ми знайшли це саме під час навантажувального тестування.

Автоматизоване, кросбраузерне та приймальне тестування

Кросбраузерність перевіряємо там, де реально сидять покупці. Статистика з Метрики конкретного проєкту важливіша за загальноринкові дані. Мінімальний набір: Chrome (останні 2 версії), Safari на iOS, Яндекс.Браузер, Samsung Internet. Пристрої: Desktop 1920×1080 та 1366×768, iPhone 375×812 та 390×844 (обов'язково чекаут), Android 360×800 та 412×915. Інструменти: BrowserStack для реальних пристроїв, Playwright для автоматизації в Chromium/Firefox/WebKit.

Автоматизація базується на Playwright — кросбраузерність, паралельний запуск, автоматичні очікування, добре працює з динамічними формами sale.order.ajax. У порівнянні з ручним тестуванням, автоматизація скорочує час виконання регресії втричі. PHPUnit використовуємо для модульних тестів кастомних компонентів і бізнес-логіки — інтеграція з CI/CD (GitLab CI, GitHub Actions). Тестовий набір із 50 сценаріїв виконується за 15 хвилин замість годин ручної перевірки.

Фінальна перевірка (UAT) проводиться із замовником на staging з копією продової бази. Спільно складаємо 15–20 ключових шляхів покупця, фіксуємо баги в Jira/YouTrack, оформляємо протокол приймання.

QA-процес: як ми вбудовуємо тестування в розробку

Тестування не приклеюється наприкінці — воно стартує з аналізу вимог.

  1. Аналіз вимог — QA бере участь в обговоренні завдань, ловить неоднозначності. «Знижка застосовується до товару чи до замовлення?» — таке питання на старті економить два дні відладки.
  2. Тест-кейси до розробки — сценарії готові до першого рядка коду.
  3. Code review — перевірка на типові помилки Бітрікса: неочищений кеш компонентів, прямі SQL-запити замість ORM, відсутність перевірки $USER->IsAuthorized().
  4. Функціональне → регресійне → деплой.
  5. Моніторинг після релізу — помилки в bitrix/error.log, метрики в аналітиці, алерти по 500-м.

Закажіть тестування сьогодні — і ми підготуємо тест-план за 2 дні.

Терміни та вартість тестування

Завдання Терміни
Тест-план 2–3 дні
Функціональне тестування (середній магазин) 3–5 днів
Базовий набір E2E-автотестів (Playwright) 2–3 тижні
Навантажувальне тестування + звіт 1–2 тижні
Кросбраузерне 2–3 дні
UAT-супровід 3–5 днів
QA-процес з нуля 3–4 тижні

Що входить у роботу: детальний тест-план із чек-листами за модулями, автоматизований набір E2E-тестів (Playwright/Cypress) під ваш стек, звіт із результатами, скріншотами помилок і рекомендаціями, інтеграція тестів у ваш CI/CD (GitLab CI, GitHub Actions, Bitbucket Pipelines), супровід UAT — до трьох ітерацій виправлень без додаткової оплати, документація процесу тестування для вашої команди.

Баг на продакшені — це не тільки вартість виправлення. Середнє виправлення критичного дефекту коштує від 20 000 грн, а втрати від зламаного кошика за вихідні на проєкті з оборотом 5 млн/міс можуть сягати 400 000 грн. Інвестиція в тестування — це страховка вашого бізнесу.

Зв'яжіться з нами, щоб отримати комерційну пропозицію та детальний план тестування для вашого проєкту.