Functional Testing of a 1C-Bitrix Website
Functional testing verifies that every feature of the site works according to requirements. It sounds straightforward, but on Bitrix projects it is systematically neglected: clicking through the site before a release does not count as testing. Without a clear test plan broken down by Bitrix modules, something always slips through — most often in the cart, search, or user account.
Test Plan by Module
Functional testing of a Bitrix project is structured around key modules. Each module has a set of mandatory checks.
Catalog and information blocks (iblock):
- Correct filtering by properties (
IBLOCK_PROPERTY, smart filter) - Sorting by price, popularity, and date — verify SQL in
b_iblock_element - Pagination without duplicate elements at page boundaries
- SEO tags and metadata on section and element pages
- Correct display of trade offers (SKU) for products with variants
Cart and order placement (sale):
- Adding a product, changing quantity, removing
- Applying coupons (
b_sale_discount_coupon) - Correct discount recalculation when cart contents change
- Selecting delivery and payment, saving the selection on page reload
- Minimum order amount restrictions
- Guest checkout (without registration)
User account (subscribe, sale, socialservices):
- Registration, login, password recovery
- Order history, repeat order
- Profile editing, email/password change
- OAuth login (VKontakte, Google, Yandex)
Search (search):
- Full-text search — results, relevance
- Morphology (Russian language, stemming)
- Search with typos — if the morphological search module is enabled
- No results — correct "nothing found" page
Technical Checks
Some checks cannot be done through clicks alone — database and log access is required.
Checking for duplicate elements on listing pages. When using multiple information blocks via CIBlockElement::GetList with a JOIN on trade offers, duplicates often appear. Check with a query:
SELECT ie.id, COUNT(*) as cnt
FROM b_iblock_element ie
JOIN b_catalog_price cp ON cp.product_id = ie.id
WHERE ie.iblock_id = 5
GROUP BY ie.id
HAVING COUNT(*) > 1;
Checking the smart filter. After product properties change or new elements are added, the smart filter may show stale data. Check index rebuild:
// Force facet index recalculation
\Bitrix\Iblock\PropertyIndex\Manager::markAsInvalid($iblockId);
\Bitrix\Iblock\PropertyIndex\Manager::updateIndex($iblockId);
Checking order events. After placing a test order, verify the presence of the expected events in b_sale_order_change_data and the correctness of sent email notifications via /bitrix/admin/mail_event_message_list.php.
Tools
For automating functional tests on Bitrix, the most common tools are:
- Playwright — for end-to-end browser flow tests (cart, checkout)
- PHPUnit — for unit tests of components and helpers
- Postman / Bruno — for REST API testing (if the project uses a custom API)
Basic e2e checkout test with Playwright:
test('checkout flow', async ({ page }) => {
await page.goto('/catalog/product-slug/');
await page.click('[data-role="add-to-cart"]');
await page.goto('/cart/');
await expect(page.locator('.cart-item')).toHaveCount(1);
await page.click('[data-role="checkout"]');
await page.fill('#phone', '+79001234567');
await page.fill('#email', '[email protected]');
await page.selectOption('#delivery', 'pickup');
await page.click('[type="submit"]');
await expect(page).toHaveURL(/\/personal\/order\/detail\//);
});
Timelines
| Project scope | Duration |
|---|---|
| Landing page / brochure site (basic functionality) | 1–2 days |
| Online store (catalog + cart + user account) | 3–6 days |
| Large e-commerce (multiple sites, B2B, integrations) | 8–15 days |







