Setting up automatic testing in CI/CD for 1C-Bitrix
Tests are written, but developers run them manually — and forget. Code goes to production without validation, tests become outdated, coverage degrades. Automatic testing in CI/CD solves the organizational problem: code cannot get to the main branch without passing tests. For Bitrix this is more complex than for Symfony or Laravel due to core dependencies and database requirements, but entirely solvable.
Pipeline architecture
A minimal CI pipeline for a Bitrix project:
- Checkout — get code from repository
- Composer install — install dependencies (PHPUnit, phpstan, php-cs-fixer)
-
Lint —
php -lfor all PHP files, syntax check - Static analysis — PHPStan / Psalm
- Unit tests — fast tests without Bitrix core
- Integration tests — tests with core and database connectivity
- Deploy (main branch only)
Docker image for CI
The main complexity — the Bitrix core. It doesn't install via Composer. Options:
Option A: core in Docker image. Create a base image with installed Bitrix, PHP and extensions. Update the image when the core is updated on the project. This is the most reliable approach.
FROM php:8.1-cli
RUN apt-get update && apt-get install -y libpq-dev libzip-dev \
&& docker-php-ext-install pdo pdo_mysql opcache zip
COPY bitrix/ /var/www/bitrix/
COPY composer.json composer.lock /var/www/
WORKDIR /var/www
RUN composer install --no-dev
Option B: core via artifact. CI downloads core from private storage (S3, GitLab Package Registry) during preparation. More flexible, but slower.
GitLab CI setup
stages:
- lint
- test
- deploy
variables:
MYSQL_DATABASE: bitrix_test
MYSQL_ROOT_PASSWORD: test
lint:
stage: lint
image: php:8.1-cli
script:
- find local/ -name "*.php" -exec php -l {} \;
- vendor/bin/phpstan analyse local/php_interface/classes/ --level 5
integration-tests:
stage: test
image: registry.example.com/bitrix-ci:latest
services:
- mysql:8.0
script:
- cp .env.ci .env
- php local/tests/setup_db.php
- vendor/bin/phpunit --configuration local/tests/phpunit.xml
artifacts:
when: always
reports:
junit: local/tests/report.xml
Key points:
-
services: mysql — starts MySQL container, accessible at hostname
mysqlinside CI - setup_db.php — script creating test database schema (minimal Bitrix table set)
- artifacts: junit — GitLab/GitHub displays test results in merge request interface
For GitHub Actions
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_DATABASE: bitrix_test
MYSQL_ROOT_PASSWORD: test
ports:
- 3306:3306
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: pdo_mysql, mbstring, zip, gd
- run: composer install
- run: vendor/bin/phpunit --configuration local/tests/phpunit.xml
Test database schema
Full Bitrix database contains 500+ tables. For integration tests you need a minimal set:
-
b_option,b_module,b_module_to_module— module configuration -
b_iblock,b_iblock_type,b_iblock_element,b_iblock_section,b_iblock_property,b_iblock_element_property— iblocks -
b_catalog_price,b_catalog_currency— catalog and currencies -
b_sale_order,b_sale_basket,b_sale_order_props_value— orders (if testing e-commerce)
Create schema dump from production: mysqldump --no-data bitrix > schema.sql. Add to repository and update when schema changes.
What must be checked in CI
PHP Lint. Trivial, but catches syntax errors in files that aren't called in manual testing. Bitrix projects often contain files included conditionally (by agent, by cron) — errors are discovered only in production.
PHPStan level 5+. At level 5, PHPStan finds calls to non-existent methods, incorrect argument types, undefined variables. For Bitrix code you'll need a phpstan-baseline.neon file to ignore core errors — the core is untyped and generates hundreds of warnings.
HTTP smoke tests. If CI raises full environment (PHP-FPM + Nginx + MySQL), add curl checks for critical URLs:
curl -f http://localhost/
curl -f http://localhost/catalog/
curl -f http://localhost/personal/cart/
Status 200 — test passes. Any other — pipeline fails.
Execution time
| Stage | Time |
|---|---|
| Lint + static analysis | 30-60 seconds |
| Unit tests (without core) | 10-30 seconds |
| Integration tests (with core and DB) | 2-10 minutes |
| Full pipeline | 5-15 minutes |
If integration tests take more than 15 minutes — split them into parallel jobs by modules. GitLab CI and GitHub Actions support parallel matrix strategies.
Setting up CI/CD for a Bitrix project is a one-day investment that pays for itself on the first prevented production bug.







