Setting Up Codeception Tests for 1C-Bitrix
We've seen it many times: an online store on Bitrix runs for years without a single automated test. Every catalog update or payment module change turns into a manual check of hundreds of scenarios. Clients complain about cart bugs, and developers dread touching legacy code. The solution is to adopt Codeception – a PHP framework that unifies unit, functional, and acceptance (E2E) tests in one tool. For Bitrix it's especially convenient: you can write functional tests that verify PHP logic without a browser, and acceptance tests via WebDriver – all in the same stack, with shared helpers and a single config.
Codeception vs. PHPUnit for Bitrix
Codeception offers advantages over PHPUnit for integration and acceptance scenarios. PHPUnit is fine for unit tests, but for integration and acceptance scenarios it requires extra infrastructure. Codeception provides ready modules: Db for database checks, WebDriver for the browser, PHPBrowser for HTTP emulation. And crucially – a modular architecture where we embed our own Bitrix helper. This helper initializes infoblocks, the cart, orders via the Sale API. Comparison: Codeception is 15 times faster than manual testing for functional checks – one functional test runs in 2 minutes instead of 30 minutes of manual checking. Our experience shows regression testing time drops by 30–50% after adoption. Typical setup costs range from $1,500 to $5,000 depending on project complexity. On average, clients save $8,000–$12,000 per year in reduced manual testing costs.
What's Included in the Setup?
We deliver a ready-to-run result:
-
codeception.yml configuration with three suites: acceptance, functional, unit.
-
Bitrix.php helper for initializing Bitrix environment, user authorization, and working with cart/orders via the CSale API.
- A set of base tests: login check, adding product to cart, order creation.
- CI/CD integration (GitLab CI / GitHub Actions) – an example
.gitlab-ci.yml.
- Documentation on running and adding new tests.
- Two weeks of consulting for the team after handover.
How Codeception Integrates with CI/CD?
We configure test execution in your continuous integration environment. For GitLab CI, we add a job that runs vendor/bin/codecept run after deploying to the test instance. Example configuration:
# .gitlab-ci.yml
codeception:
stage: test
script:
- composer install --no-progress
- cp .env.testing .env
- php vendor/bin/codecept run
only:
- develop
Similarly for GitHub Actions. Tests run in headless mode, without a real browser for the functional suite, and with WebDriver for acceptance. Integration takes no more than a day and guarantees every push is automatically verified.
How We Set Up Codeception (Step by Step)
-
Analyze the project – examine Bitrix version, directory structure, used modules (sale, catalog, iblock).
- Install packages via Composer and configure
codeception.yml.
- Write the Bitrix helper – correctly include the prolog, avoid session conflicts and static file issues. Use constants like
NO_KEEP_STATISTIC, NOT_CHECK_PERMISSIONS, BX_WITH_ON_AFTER_EPILOG – standard solutions from the Bitrix documentation.
- Write several tests for critical functionality – catalog, cart, checkout.
- Integrate with CI/CD – so tests run automatically on every push.
Example: Functional Test for Order Creation
Here's a functional test that creates an order using the Sale API. It uses the helper to authorize and add a product to the cart:
// tests/Functional/OrderCest.php
namespace Tests\Functional;
use Tests\Support\FunctionalTester;
class OrderCest
{
public function _before(FunctionalTester $I): void
{
// Clear the cart before each test
$I->executeQuery('DELETE FROM b_sale_basket WHERE FUSER_ID = ?', [1]);
}
public function addItemAndCreateOrder(FunctionalTester $I): void
{
// Add product to cart via helper
$I->loginAs('testuser', 'testpassword');
$count = $I->addProductToCart(42, 2);
$I->assertEquals(1, $count, 'Cart should have 1 product');
// Create order via Sale API
$I->executeCustomAction(function () {
\Bitrix\Main\Loader::includeModule('sale');
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(1, 's1');
$order = \Bitrix\Sale\Order::create('s1', 1); // site, user
$order->setBasket($basket);
$order->setField('CURRENCY', 'RUB');
$propertyCollection = $order->getPropertyCollection();
$prop = $propertyCollection->getPayerName();
$prop?->setValue('Тестовый Пользователь');
$result = $order->save();
return $result;
}, function ($result) use ($I) {
$I->assertTrue($result->isSuccess(), implode(', ', $result->getErrorMessages()));
});
// Verify order exists in database
$I->seeInDatabase('b_sale_order', [
'USER_ID' => 1,
'CURRENCY' => 'RUB',
'STATUS_ID' => 'N',
]);
}
}
Acceptance Test via WebDriver
For UI verification we use WebDriver with Chrome in headless mode. Example: filtering catalog by brand.
// tests/Acceptance/CatalogCest.php
namespace Tests\Acceptance;
use Tests\Support\AcceptanceTester;
class CatalogCest
{
public function filterByBrandShowsCorrectProducts(AcceptanceTester $I): void
{
$I->amOnPage('/catalog/tools/');
$I->waitForElement('.catalog-filter', 10);
// Apply brand filter
$I->checkOption('[data-filter="brand"][value="bosch"]');
$I->waitForElementNotVisible('.catalog-loading', 10);
// Check URL
$I->seeInCurrentUrl('brand=bosch');
// Verify all product cards are Bosch
$I->seeNumberOfElementsGreaterThan('.product-card', 0);
$brands = $I->grabMultiple('.product-brand');
foreach ($brands as $brand) {
$I->assertEquals('Bosch', $brand);
}
}
}
Common mistakes when writing tests include: using die() or exit() in the helper, ignoring database cleanup after tests, hardcoding product and user IDs, and running acceptance tests on production instead of a database copy. We always use a separate test database to avoid data corruption.
Test Type Comparison
| Test Type |
Speed |
What It Checks |
Tool |
Writing Time |
| Unit |
~1 ms |
Class, method |
PHPUnit |
5-10 min |
| Functional |
~100 ms |
Business logic, DB |
Codeception + PHPBrowser |
30-60 min |
| Acceptance |
~2 s |
UI, JS, layout |
Codeception + WebDriver |
1-3 h |
Timeline and Process
| Step |
Task |
Duration |
| Analysis |
Study project, version, dependencies |
1 day |
| Development |
Install Codeception, write helper, configure suites |
1-2 days |
| Writing tests |
Functional tests for business logic (orders, cart, calculations) |
1-3 days |
| Acceptance tests |
WebDriver tests for catalog, checkout, authorization |
2-4 days |
| Integration |
Embed into CI/CD, verify stability |
1 day |
| Documentation |
Developer guide, helper description |
1 day |
Our engineers have 5+ years of experience with Bitrix and Codeception. We've implemented testing for 30+ projects – from small online stores to large trade portals with 50,000 products. We guarantee the tests run in your environment without modifications and provide two weeks of free support after handover.
Want to eliminate manual regression for good? Contact us for a project assessment and a 1-day implementation plan. Order Codeception setup and get a solid foundation for test automation.
Duplicate Products on Page 3: A Bug That Goes to Production
A real case: an online store with pagination through bitrix:catalog.section duplicates products on page three after every second visit. Cache clearing helps for a day, then the duplicates return. Root cause: a custom sort handler collides with PAGEN_1, and under a specific filter combination CIBlockElement::GetList returns identical IDs. Code review missed it; only testing caught it. We build QA for 1C-Bitrix projects that catches such bugs before they hit production: manual functional, automated E2E, load, and acceptance testing. With over a decade of Bitrix experience, we have a library of typical pitfalls and test scenarios that prevent these issues from the start.
How Does a Standard Bitrix Project Break Without Dedicated Testing?
1C-Bitrix is not a landing page. Behind the frontend lie dozens of modules, external integrations, and non‑obvious dependencies. A discount change in sale.discount breaks a promo code in sale.basket.discount — the discount module is one of the most fragile in the platform. Interchange with 1C via catalog.import.1c or REST fails when property mapping is off, resulting in products without price or stock. Core updates — bitrix:main updated, a custom component uses the deprecated CModule::IncludeModule. Without regression testing, every deployment is Russian roulette. Cross‑browser: sale.order.ajax renders differently in Safari and Chrome; the “Place Order” button can move off‑screen on an iPhone. These are not edge cases — they are daily realities for Bitrix teams.
What Does Functional Testing Cover?
We check every business scenario — not just “works or doesn’t work”, but all boundary cases.
Catalog (catalog.section, catalog.element)
- Smart filter
catalog.smart.filter: all property combinations, reset, result counting. Filters by SKUs break most often.
- Sorting + pagination — the duplicate bug described above.
- Comparison via
catalog.compare.list — add, remove, display differences.
- Quick view — modal window, cart from modal.
Cart and Order (sale.basket.basket, sale.order.ajax)
- Adding from catalog, product page, quick order.
- Discounts: by quantity, by amount, by coupon, cumulative. Discount intersection — at least eight test combinations.
- Delivery calculation: handlers
sale.delivery.services, cost, time, pickup points on map.
- Payment:
sale.paysystem — processing, handling declines, refunds.
- Order placement: email via
main.mail.event, CRM recording, transmission to 1C via sale.export.1c.
Personal Account (sale.personal.section)
- Registration, authorization, password recovery — including Cyrillic email edge cases.
- Order history, repeat order.
- Subscriptions, bonus program.
Forms and Search
-
form.result.new / iblock.element.add.form — submission, validation, file fields.
-
search.page — relevance, morphology, typo handling via search.title.
Why Is Regression Testing Critical for Bitrix?
After every deployment we verify that nothing previously working is broken.
-
Smoke tests — main page loads, catalog shows products, order completes. 5 minutes, run after every deploy. If smoke fails — roll back immediately.
-
Regression suite — 40–80 test cases covering main scenarios before every release.
-
Visual testing — screenshot comparison (Percy or Playwright). A button shifted 20px, font changed after update — test shows the diff.
-
Module checklists — structured lists for
sale, catalog, iblock, search. Each module has its own checklist.
What Happens During Load Testing?
The question is not “will the site handle it” but at how many concurrent users catalog.section starts returning 500 errors.
| Scenario |
Share |
Target Response |
What Breaks First |
| Main page |
20% |
< 1 sec |
Composite cache if not configured |
| Catalog with filters |
30% |
< 2 sec |
MySQL – heavy JOINs on b_iblock_element_property |
| Product page |
25% |
< 1.5 sec |
Queries for SKUs |
| Add to cart |
10% |
< 1 sec |
Table locks on b_sale_basket |
| Checkout |
5% |
< 3 sec |
Delivery handlers (external APIs) |
| Search |
10% |
< 2 sec |
b_search_content without indexes |
Tools:
-
k6 — JavaScript scripting.
- Apache JMeter — classic, for complex scenarios with cookie authorization.
- Yandex.Tank — real‑time visualization, integration with Overload.
Output: peak RPS, response times by percentiles p50/p95/p99, bottlenecks (CPU, RAM, MySQL slow queries on b_iblock_element, file cache). Recommendations: which index to add, which query to rewrite with D7 ORM, where to enable composite cache.
What Deliverables Do You Receive After Testing?
- Test plan with scope, priorities, and quality criteria.
- Test case suite — functional, regression, load.
- Defect report in a tracker (Jira/YouTrack) with severity classification.
- Auto tests (Playwright/Cypress) — basic smoke suite for CI/CD.
- Load testing protocol with graphs and recommendations.
- Acceptance certificate after UAT — confirming readiness for launch.
After delivery, we provide free consultation for a month — answering questions on test improvements and process adaptation. Contact us to receive a full package of documents and auto tests.
Cross‑Browser Testing
We test where buyers actually are. Statistics from your Metrica are more important than general market data.
Minimum set:
- Chrome (last 2 versions) — main traffic.
- Safari on iOS — critical for mobile checkout,
sale.order.ajax often behaves unpredictably.
- Yandex.Browser — significant share in Russia, Chromium‑based but with extension quirks.
- Samsung Internet — mobile Android, often forgotten.
Devices:
- Desktop: 1920×1080, 1366×768.
- iPhone: 375×812, 390×844 — checkout must be verified.
- Android: 360×800, 412×915.
Tools: BrowserStack for real devices, Playwright for automation on Chromium/Firefox/WebKit.
Automation
Playwright — primary choice for E2E on Bitrix:
- Cross‑browser: Chromium, Firefox, WebKit.
- Parallel execution, automatic waits.
- Works well with dynamic forms
sale.order.ajax.
- Supports mobile viewports and geolocation.
Cypress:
- Runs in browser — more stable for SPA‑like interfaces.
- Excellent visual runner for debugging.
- Limitation: only Chromium‑based browsers.
PHPUnit for custom code:
- Unit tests for custom Bitrix components and modules.
- Tests business logic without frontend dependency.
- Integration with CI/CD — GitLab CI, GitHub Actions.
UAT – Acceptance Testing
Final check with the client on a staging environment with real data:
- Jointly compile a list of critical scenarios — 15–20 key customer paths, not 200 test cases.
- Staging with a copy of the production database (anonymized personal data).
- Quick bug tracking — Jira/YouTrack, prioritization by severity.
- Acceptance protocol — document with results, signatures, and launch readiness.
Order UAT support and we guarantee a release without surprises.
QA Process – Integrated, Not Tacked On
-
Requirements analysis — QA participates in task discussions, catches ambiguities. “Does the discount apply to the product or the order?” — such a question upfront saves two days of debugging.
-
Test cases before development — scenarios ready before the first line of code.
-
Code review — checks for typical Bitrix mistakes: uncleared component cache, direct SQL queries instead of ORM, missing
$USER‑>IsAuthorized() check.
-
Functional → regression → deploy.
-
Post‑release monitoring — errors in
bitrix/error.log, metrics in Metrica, alerts for 500 errors.
We have been working with Bitrix for over 10 years and have tested more than 300 projects of various scales — from small online stores to corporate portals with 1C and Bitrix24 integration.
Timelines
| Task |
Duration |
| Test plan |
2–3 days |
| Functional testing (medium store) |
3–5 days |
| Basic E2E auto test suite (Playwright) |
2–3 weeks |
| Load testing + report |
1–2 weeks |
| Cross‑browser testing |
2–3 days |
| UAT support |
3–5 days |
| QA process from scratch |
3–4 weeks |
Testing cost is calculated individually for your project. Get a free consultation — we will assess the scope within one business day and provide a preliminary estimate and test plan. Contact us to discuss your project and schedule a call.