Development of an automated testing system for 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

Automated Testing System Development for 1C-Bitrix

Bitrix core updates every two weeks, continuous feature development, 1C integration — manual regression testing takes 4–8 hours after every change. Automated tests reduce this to 10–15 minutes and provide confidence that core functionality is working. The difficulty is that Bitrix is a monolithic framework with global state that does not lend itself to test isolation. Specific infrastructure is required.

Testing Stack

For Bitrix projects, the following combination is recommended:

  • PHPUnit — unit tests for isolatable business logic
  • Codeception — functional and integration tests (has a Bitrix module)
  • Playwright / Puppeteer — e2e tests for browser behavior
  • PHPStan — static analysis (not a test, but part of CI)

Infrastructure for Unit Tests

The main challenge of unit testing Bitrix is that the code depends on global state: \Bitrix\Main\Application::getInstance(), \CMain, $DB. Running a test without initializing the Bitrix core is not possible.

Solution — load the core in the test bootstrap file:

// tests/bootstrap.php
$_SERVER['DOCUMENT_ROOT'] = dirname(__DIR__);
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('BX_WITH_ON_AFTER_EPILOG', false);

require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

phpunit.xml:

<phpunit bootstrap="tests/bootstrap.php">
    <testsuites>
        <testsuite name="Unit">
            <directory>tests/unit</directory>
        </testsuite>
    </testsuites>
</phpunit>

What Unit Tests Cover

Business logic isolated in classes without direct core dependencies:

class ArticleResolverTest extends TestCase
{
    public function testResolveValidArticle(): void
    {
        // Mock the IBlock API dependency
        $resolver = new ArticleResolver($this->createMockRepository());
        $result = $resolver->resolve('ABC-123', CATALOG_IBLOCK_ID);
        $this->assertSame(456, $result->getSkuId());
    }

    public function testResolveUnknownArticleReturnsNull(): void
    {
        $resolver = new ArticleResolver($this->createEmptyRepository());
        $this->assertNull($resolver->resolve('UNKNOWN', CATALOG_IBLOCK_ID));
    }
}

The key pattern: dependency injection instead of direct static method calls to Bitrix — this is what makes code testable.

Functional Tests with Codeception

Codeception with the Bitrix module allows testing HTTP scenarios without a browser:

// tests/functional/OrderCheckoutCest.php
class OrderCheckoutCest
{
    public function addToCartAndCheckout(FunctionalTester $I): void
    {
        $I->amOnPage('/catalog/product-slug/');
        $I->click('Add to cart');
        $I->seeInDatabase('b_sale_basket', ['PRODUCT_ID' => 123]);

        $I->amOnPage('/order/');
        $I->fillField('NAME', 'Test User');
        $I->fillField('EMAIL', '[email protected]');
        $I->click('Place order');
        $I->seeInDatabase('b_sale_order', ['STATUS_ID' => 'N']);
    }
}

E2E Tests with Playwright

For critical user paths — e2e tests that launch a real browser:

// tests/e2e/checkout.spec.js
test('full checkout flow', async ({ page }) => {
    await page.goto('/catalog/product-slug/');
    await page.click('.add-to-cart-btn');
    await expect(page.locator('.cart-count')).toHaveText('1');

    await page.goto('/order/');
    await page.fill('[name="NAME"]', 'Test User');
    await page.fill('[name="EMAIL"]', '[email protected]');
    await page.click('.submit-order-btn');
    await expect(page).toHaveURL(/\/order\/success\//);
});

CI/CD Integration

Tests run automatically on every push to the repository. GitHub Actions / GitLab CI:

# .github/workflows/tests.yml
test:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v3
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.1'
    - run: composer install
    - run: vendor/bin/phpunit --testsuite Unit
    - run: vendor/bin/codecept run functional
Test type Tool Execution time Coverage
Unit (isolated logic) PHPUnit 30–60 s Resolution, calculations, mapping
Functional Codeception 2–5 min Cart, order, forms
E2E Playwright 5–10 min Critical user paths
Static analysis PHPStan 1–2 min All PHP code

What Is Included in Testing System Development

  • PHPUnit bootstrap environment setup for loading Bitrix in test mode
  • Code refactoring for dependency injection and testability
  • Writing unit tests for core business logic
  • Codeception setup for functional HTTP scenario tests
  • E2e tests with Playwright for critical user paths
  • CI/CD integration (GitHub Actions, GitLab CI)