Ми знаємо: модуль Бітрікс без тестів — чорний ящик. Виправили одне — зламали інше. Особливо болісно це в модулях з бізнес-логікою: розрахунок знижок, інтеграції з зовнішніми 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 для модуля Бітрікс?
- Проведіть аудит модуля. Визначте критичні ділянки бізнес-логіки, які варто покрити тестами першочергово. Ми оцінюємо поточну архітектуру і пропонуємо план рефакторингу.
- Налаштуйте bootstrap та phpunit.xml. Створіть два режими: unit-тести без ядра (швидкі, секунди) та integration-тести з ядром (хвилини). Додайте автозавантаження Composer.
- Напишіть тести для бізнес-логіки. Використовуйте моки для ізоляції. Для кожного сервісу — окремий тест-кейс.
- Інтегруйте CI/CD. Налаштуйте запуск unit-тестів при кожному пуші, integration-тестів перед мержем. Використовуйте GitHub Actions або GitLab CI.
- Підтримуйте покриття. Регулярно оновлюйте тести при змінах. Ми навчаємо вашу команду писати нові тести.
Структура тестів у модулі
/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 днів після запуску — ми допоможемо усунути будь-які питання.







