w-funnel/docs/AB_TESTING_GUIDE.md
2025-10-22 22:42:01 +02:00

386 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🧪 AB Testing с Unleash в Воронках
Полное руководство по интеграции AB тестов через Unleash feature flags в систему воронок.
## 📋 Содержание
- [Настройка](#настройка)
- [Примеры использования](#примеры-использования)
- [API Reference](#api-reference)
- [Архитектура](#архитектура)
## 🔧 Настройка
### 1. Environment Variables
Добавьте в `.env.local`:
```bash
NEXT_PUBLIC_UNLEASH_URL=https://your-unleash-instance.com/api/frontend
NEXT_PUBLIC_UNLEASH_CLIENT_KEY=your-client-key
```
**Важно:** Если переменные не установлены, AB тесты будут отключены автоматически.
### 2. Настройка Unleash Dashboard
1. Создайте feature flag в Unleash (например, `trial-button-test`)
2. Добавьте варианты (v0, v1, v2, etc.)
3. Настройте stickiness на `sessionId` для консистентности
4. Добавьте gradual rollout strategy
## 💡 Примеры использования
### Пример 1: AB тест текста кнопки
**Сценарий:** Тестируем разные тексты кнопки оплаты
```json
{
"id": "payment-screen",
"template": "trialPayment",
"bottomActionButton": {
"text": "Continue"
},
"variants": [
{
"conditions": [
{
"screenId": "payment-screen",
"conditionType": "unleash",
"unleashFlag": "trial-button-test",
"unleashVariants": ["v1"],
"operator": "includesAny"
}
],
"overrides": {
"bottomActionButton": {
"text": "Start 3-Day Trial"
}
}
},
{
"conditions": [
{
"screenId": "payment-screen",
"conditionType": "unleash",
"unleashFlag": "trial-button-test",
"unleashVariants": ["v2"],
"operator": "includesAny"
}
],
"overrides": {
"bottomActionButton": {
"text": "Get My Reading Now"
}
}
}
]
}
```
**Результат:**
- v0 (контроль): "Continue"
- v1: "Start 3-Day Trial"
- v2: "Get My Reading Now"
### Пример 2: AB тест навигации
**Сценарий:** Тестируем короткий vs длинный onboarding
```json
{
"id": "gender-select",
"template": "list",
"navigation": {
"defaultNextScreenId": "birthdate",
"rules": [
{
"conditions": [
{
"screenId": "gender-select",
"conditionType": "unleash",
"unleashFlag": "onboarding-flow-test",
"unleashVariants": ["short"],
"operator": "equals"
}
],
"nextScreenId": "payment"
},
{
"conditions": [
{
"screenId": "gender-select",
"conditionType": "unleash",
"unleashFlag": "onboarding-flow-test",
"unleashVariants": ["long"],
"operator": "equals"
}
],
"nextScreenId": "relationship-status"
}
]
}
}
```
**Результат:**
- v0/default: gender → birthdate
- short: gender → payment (пропускаем шаги)
- long: gender → relationship-status → ... → payment
### Пример 3: Комбинированные условия
**Сценарий:** AB тест только для женской аудитории
```json
{
"variants": [
{
"conditions": [
{
"screenId": "gender",
"conditionType": "options",
"optionIds": ["female"],
"operator": "includesAny"
},
{
"screenId": "payment",
"conditionType": "unleash",
"unleashFlag": "female-specific-test",
"unleashVariants": ["v1"],
"operator": "equals"
}
],
"overrides": {
"title": {
"text": "Special offer for you! ✨"
}
}
}
]
}
```
## 📚 API Reference
### NavigationConditionDefinition
```typescript
interface NavigationConditionDefinition {
screenId: string;
conditionType?: "options" | "values" | "unleash";
operator?: "includesAny" | "includesAll" | "includesExactly" | "equals";
// Для Unleash AB тестов
unleashFlag?: string;
unleashVariants?: string[];
// Для других типов
optionIds?: string[];
values?: string[];
}
```
### Операторы
| Оператор | Описание | Пример |
|----------|----------|--------|
| `includesAny` | Хотя бы один вариант совпадает | `["v1", "v2"]` → true если v1 ИЛИ v2 |
| `includesAll` | Все варианты совпадают | `["v1"]` → true если v1 (для одного = includesAny) |
| `includesExactly` | Только указанные варианты | Редко используется |
| `equals` | Точное совпадение | `["v1"]` → true только если v1 |
### Типы условий
| Тип | Использование | Пример |
|-----|---------------|--------|
| `options` | List экраны | `{ conditionType: "options", optionIds: ["male"] }` |
| `values` | Зодиак, возраст | `{ conditionType: "values", values: ["aries", "leo"] }` |
| `unleash` | AB тесты | `{ conditionType: "unleash", unleashFlag: "test-1" }` |
## 🏗 Архитектура
### Компоненты
```
UnleashProvider (от @unleash/proxy-client-react)
└── FunnelUnleashWrapper (собирает все флаги из воронки)
└── UnleashContextProvider (предоставляет активные варианты)
└── FunnelRuntime (использует варианты для navigation/variants)
```
### Поток данных
1. **FunnelUnleashWrapper** сканирует все экраны воронки
2. Находит все `unleashFlag` в conditions
3. Получает варианты для всех флагов через `useVariant`
4. Передает `{ flagName: variant }` в **UnleashContextProvider**
5. **FunnelRuntime** использует `unleashChecker` для проверки условий
6. **navigation.ts** и **variants.ts** вызывают `unleashChecker` при проверке
### Файловая структура
```
src/
├── lib/funnel/
│ ├── unleash/
│ │ ├── UnleashProvider.tsx # Wrapper для Unleash SDK
│ │ ├── UnleashContext.tsx # Context с активными вариантами
│ │ ├── useUnleash.ts # Hook для получения вариантов
│ │ └── index.ts
│ ├── navigation.ts # Поддержка unleash в условиях
│ ├── variants.ts # Поддержка unleash в вариантах
│ └── types.ts # Расширенные типы
├── components/
│ ├── funnel/
│ │ ├── FunnelUnleashWrapper.tsx # Сборщик флагов
│ │ └── FunnelRuntime.tsx # Интеграция unleashChecker
│ └── admin/builder/forms/
│ ├── UnleashConditionEditor.tsx # UI для настройки
│ ├── ConditionTypeSelector.tsx # Выбор типа
│ └── variants/
│ └── VariantConditionEditor.tsx # Интеграция в существующий UI
```
## 🎯 Best Practices
### 1. Naming Convention
```bash
# Формат: [page]-[element]-[description]
trial-button-text
onboarding-flow-length
payment-copy-variant
```
### 2. Variants Naming
```bash
# Всегда используйте v0 как контроль
v0 - контрольная группа (baseline)
v1 - вариант 1
v2 - вариант 2
```
### 3. Stickiness
**Всегда используйте `sessionId` для stickiness** в Unleash:
- Обеспечивает консистентность для анонимных пользователей
- Пользователь видит одинаковый вариант на всех экранах
- Не требует авторизации
### 4. Rollout Strategy
```bash
# Начните с малого
Week 1: 10% traffic → v1
Week 2: 50% traffic → v1
Week 3: 100% traffic → v1 (если winner)
```
## 🔍 Debugging
### Development Mode
В development режиме в консоли будут логи:
```bash
[Unleash] Flag "trial-button-test" = v1
[Unleash] Active variants: { "trial-button-test": "v1", "onboarding-flow": "short" }
```
### Query Parameters (только dev)
```bash
# Переопределить вариант флага
?trial-button-test=v2
# Комбинировать несколько
?trial-button-test=v1&onboarding-flow=short
```
### Admin Preview
В админке конструктора:
1. Экраны с AB тестами помечены значком 🧪
2. В превью можно переключать варианты
3. Validation показывает некорректные флаги
## ⚠️ Troubleshooting
### Флаг не работает
**Проверьте:**
1. ✅ Environment variables установлены
2. ✅ Флаг создан в Unleash Dashboard
3. ✅ Флаг включен (enabled)
4. ✅ Правильно указано `unleashFlag` в JSON
5. ✅ Варианты существуют в Unleash
### Всегда показывается контроль
**Причины:**
- Rollout = 0% (увеличьте в Unleash)
- Неправильный stickiness (используйте sessionId)
- Constraints блокируют пользователя
### Ошибка в консоли
```bash
Cannot find module '@/lib/funnel/unleash'
```
**Решение:** Проект не собран. Выполните `npm run dev`
## 📊 Analytics Integration
Unleash автоматически отправляет impression events:
```typescript
window.gtag?.("event", "experiment_impression", {
app_name: "witlab-funnel",
feature: "trial-button-test",
treatment: "v1"
});
```
Интегрируется с:
- ✅ Google Analytics
- ✅ Google Tag Manager
- ✅ Yandex Metrika (через funnel meta)
## 🚀 Deployment
### Перед выкаткой
```bash
# 1. Проверьте сборку
npm run build
# 2. Проверьте все флаги в Unleash
# 3. Убедитесь что rollout = 0% для новых тестов
# 4. Deploy
```
### После выкатки
```bash
# 1. Проверьте метрики через 1 час
# 2. Постепенно увеличивайте rollout
# 3. Анализируйте результаты через 1-2 недели
# 4. Выберите winner и удалите проигравшие варианты
```
## 📞 Support
**Вопросы?** Проверьте:
1. Эту документацию
2. Примеры в `/public/funnels/`
3. Код в `/src/lib/funnel/unleash/`
**Нашли баг?** Создайте issue с:
- Название флага
- JSON конфигурация
- Ожидаемое vs фактическое поведение