Розробка модуля A/B-тестування для 1С-Бітрікс

Випадковий розподіл варіантів в A/B-тестах на Бітрікс спотворює результати та призводить до хибних висновків. Ми розробляємо кастомні модулі A/B-тестування з детермінованим призначенням варіантів, що забезпечує чистоту експерименту та надійність даних. Наша команда реалізує проєкт під ключ — від аудиту до впровадження та подальшої підтримки.

Розробка модуля A/B-тестування для 1С-Бітрікс

ТестуванняСередній~2-3 дні
Часті запитання

Розробка модуля A/B-тестування для 1С-Бітрікс

Випадкове (rand()) призначення варіантів у A/B-тесті — причина провалу більшості експериментів на Бітрікс. Користувач бачить то один варіант, то інший — дані втрачають сенс, а статистика стає марною. У 30% випадків таке розділення аудиторії призводить до хибних висновків і неправильних бізнес-рішень. Навіть модулі з Маркетплейсу часто використовують session_id без прив'язки до користувача, що дає sample ratio mismatch (SRM). Ми пропонуємо кастомний модуль vendor.abtest з детермінованим призначенням на основі crc32-хешу, трекінгом конверсій через події Бітрікс і розрахунком статистичної значущості (p-value, uplift, SRM). Оцінимо ваш проект за один день. За 5+ років роботи ми реалізували понад 20 модулів A/B-тестування для Бітрікс-проектів — від невеликих інтернет-магазинів до великих каталогів із 50 000+ відвідувачами на місяць. Ми гарантуємо коректність статистики та відсутність SRM, маємо сертифікацію 1С-Бітрікс.

Детерміноване призначення варіанту

Ключове завдання — один користувач завжди бачить один і той самий варіант. Призначення виконується один раз і зберігається в таблиці b_vendor_ab_assignment. Використовуємо хеш crc32(session_id + experiment_code) для стабільного потрапляння у відсоток трафіку — без зберігання зайвих даних. Порівняно з rand(), детерміноване призначення в 20 разів стабільніше та виключає спотворення вибірки (SRM).

class AssignmentService {
    public function getVariant(string $experimentCode): ?Variant {
        $experiment = ExperimentTable::getByCode($experimentCode);
        if (!$experiment || $experiment['STATUS'] !== 'running') return null;
        $sessionId = $this->getSessionId();
        $userId = $GLOBALS['USER']->GetID() ?: null;
        $existing = AssignmentTable::getList([
            'filter' => [
                'EXPERIMENT_ID' => $experiment['ID'],
                'LOGIC' => 'OR',
                'USER_ID' => $userId,
                'SESSION_ID' => $sessionId,
            ],
        ])->fetch();
        if ($existing) {
            return VariantTable::getById($existing['VARIANT_ID'])->fetch();
        }
        $hash = crc32($sessionId . $experimentCode) % 100;
        if ($hash >= $experiment['TRAFFIC_PERCENT']) return null;
        $variant = $this->selectVariant($experiment['ID']);
        AssignmentTable::add([
            'EXPERIMENT_ID' => $experiment['ID'],
            'VARIANT_ID' => $variant['ID'],
            'USER_ID' => $userId,
            'SESSION_ID' => $sessionId,
        ]);
        return $variant;
    }
}

Порівняння: детерміноване призначення vs rand()

Критерій rand(0,1) Детермінований хеш
Стабільність варіанту Ні (змінюється при перезавантаженні) Так (завжди один і той самий)
Коректність статистики Ні (один користувач — кілька варіантів) Так (кожен користувач — одне спостереження)
Можливість масштабування Тільки 2 варіанти Будь-яка кількість, з вагами

Чому важлива статистична значущість?

Без неї можна прийняти випадкову флуктуацію за покращення. В адмінці модуля розраховуємо:

  • Конверсія = події / учасники
  • p-value за критерієм хі-квадрат (поріг 0.05)
  • Uplift відносно контролю
  • Sample ratio mismatch — перевірка коректності розділення
function chiSquaredTest(int $a_visitors, int $a_conversions, int $b_visitors, int $b_conversions): float {
    $a_rate = $a_conversions / $a_visitors;
    $b_rate = $b_conversions / $b_visitors;
    $pooled = ($a_conversions + $b_conversions) / ($a_visitors + $b_visitors);
    $expected_a = $pooled * $a_visitors;
    $expected_b = $pooled * $b_visitors;
    return (($a_conversions - $expected_a) ** 2 / $expected_a) + (($b_conversions - $expected_b) ** 2 / $expected_b);
}

Джерело: Wikipedia – Chi-squared test

Інтеграція модуля в шаблони

У шаблоні компонента або лейауті:

$abTest = \Vendor\AbTest\AbTestService::getInstance();
$variant = $abTest->getVariant('checkout_button_color');
$buttonClass = match ($variant?->getName()) {
    'green' => 'btn-success',
    'orange' => 'btn-warning',
    default => 'btn-primary',
};

У JavaScript — через data-атрибут або глобальну змінну window.ABTEST_VARIANTS. Не забувайте перевіряти, що сервіс повернув об'єкт, інакше виводити контрольну версію. JavaScript SDK модуля автоматично збирає події кліків і відправляє їх через REST, що виключає втрату даних при перезавантаженні. Впровадження модуля в 2 рази швидше, ніж розробка з нуля власними силами.

Реальний кейс

На одному з проектів інтернет-магазину з 50 000 відвідувачів на місяць ми впровадили модуль A/B-тестування для оптимізації кнопки замовлення. Детерміноване призначення дозволило за 2 тижні отримати статистично значущий приріст конверсії на 12%. Без модуля такий результат був би недосяжним через міграцію користувачів між варіантами. Економія на помилкових рішеннях склала більше 1500 $ на місяць.

Що входить у розробку?

  • ORM-таблиці експериментів, варіантів, призначень і подій
  • Сервіс детермінованого призначення з підтримкою ваг
  • Трекінг цільових подій через агенти та події
  • Адміністративний інтерфейс зі статистикою та експортом
  • JavaScript SDK для фронтенду
  • Документація та код-рев'ю
  • Тестування на тестовому полігоні
  • Гарантія на модуль — 12 місяців

Процес роботи

  1. Аналітика — разом з вами визначаємо цілі експерименту, гіпотези та ключові метрики.
  2. Проектування — проектуємо ORM-схему, API та інтерфейс статистики.
  3. Реалізація — пишемо сервіс призначення, трекінг і адмінку.
  4. Тестування — перевіряємо коректність призначення, відсутність зміщення та точність розрахунків.
  5. Деплой — встановлюємо модуль на бойовий сервер і проводимо A/B-тест під вашим контролем.

Строки та вартість розробки

Етап Строк Вартість
ORM-таблиці, детерміноване призначення 2 дні 400 $
Трекінг подій, інтеграція з продажами 2 дні 400 $
Статистика, χ² тест 2 дні 400 $
JavaScript SDK для фронтенду 1 день 200 $
Адміністративний інтерфейс 2 дні 400 $
Тестування 1 день 200 $
Разом 10 робочих днів 2000 $

Мультиваріантне тестування (3+ варіанти) та серверні feature-флаги потребують окремої оцінки.

Типові помилки A/B тестування на Бітрікс

  • Використання rand() без фіксації варіанту — ламає статистику.
  • Плутанина з session_id на мобільних пристроях — призначення має бути прив'язане до авторизованого користувача.
  • Ігнорування sample ratio mismatch — якщо розподіл відхилився від заданого, довіряти результатам не можна.
  • Раннє завершення тесту — мінімальний розмір вибірки має бути розрахований заздалегідь.

Зв'яжіться з нами, щоб обговорити ваш експеримент — ми підберемо оптимальну архітектуру модуля під ваше завдання. Отримайте консультацію з впровадження A/B тестів уже сьогодні. Замовте розробку модуля A/B-тестування — інструмент для об'єктивних експериментів підвищить конверсію вашого магазину. Ми — досвідчені фахівці з сертифікацією 1С-Бітрікс, гарантуємо якість та результати.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060
  • Розробка віджета онлайн-запису для медичного центру
    Розробка віджета онлайн-запису для медичного центру
    837
  • Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    928
  • Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    865
  • Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1223