Pular para conteúdo

AB_TEST - A/B Testing e Experimentação

O que é este Node?

O AB_TEST é o node responsável por rastrear experimentos A/B, registrando qual variante usuário viu e se converteu, permitindo análise estatística de resultados.

Por que este Node existe?

A/B testing valida hipóteses com dados. O AB_TEST existe para:

  1. Test Hypotheses: Validar ideias com dados reais
  2. Optimize Conversion: Descobrir o que funciona melhor
  3. Reduce Risk: Testar antes de lançar para todos
  4. Statistical Significance: Resultados confiáveis estatisticamente

Como funciona internamente?

Quando o AB_TEST é executado, o sistema:

  1. Registra exposição: Usuário viu variante A ou B
  2. Rastreia conversão: Se usuário converteu
  3. Calcula estatísticas: Conversion rate por variante
  4. Determina winner: Variante com melhor performance

Código interno (analytics-executor.service.ts:474-494):

private async trackABTest(data: any, userId: string, sessionId: string, context: any): Promise<any> {
  const abTest = {
    type: 'a_b_test',
    experimentId: data.experimentId,
    experimentName: data.experimentName,
    variant: data.variant,
    converted: data.converted || false,
    userId: userId,
    sessionId: sessionId,
    timestamp: new Date().toISOString()
  };

  await this.storeTrackingEvent(abTest);

  return {
    success: true,
    action: 'ab_test_tracked',
    data: abTest,
    timestamp: abTest.timestamp
  };
}

Quando você DEVE usar este Node?

Use AB_TEST para experimentação controlada:

Casos de uso

  1. Landing Pages: Testar headlines, CTA buttons
  2. Pricing: Testar diferentes preços
  3. Onboarding: Testar fluxos de ativação
  4. Features: Testar novo design/funcionalidade
  5. Copy: Testar mensagens marketing

Quando NÃO usar AB_TEST

  • Mudanças pequenas: Não vale estatisticamente
  • Pouco tráfego: Precisa de volume para significância
  • Múltiplas variáveis: Use multivariate testing

Parâmetros Detalhados

experimentId (string, obrigatório)

O que é: Identificador único do experimento.

experimentName (string, obrigatório)

O que é: Nome descritivo do experimento.

variant (string, obrigatório)

O que é: Qual variante usuário viu (control, variant_a, variant_b).

converted (boolean, opcional)

O que é: Se usuário converteu após ver variante.

Flow completo para testar:

{
  "name": "AB Test - CTA Button Color",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Random Variant",
        "parameters": {
          "name": "variant",
          "value": "{{$random(['control', 'variant_a'])}}"
        }
      }
    },
    {
      "id": "tracking_1",
      "type": "tracking",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Track Exposure",
        "parameters": {
          "trackingType": "a_b_test",
          "data": {
            "experimentId": "exp_button_color_001",
            "experimentName": "CTA Button Color Test",
            "variant": "{{variant}}",
            "converted": false
          }
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Check Variant",
        "parameters": {
          "variable": "variant",
          "operator": "equals",
          "value": "control"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Control: Blue Button",
        "parameters": {
          "message": "🔵 Clique aqui (azul)"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 150 },
      "data": {
        "label": "Variant A: Red Button",
        "parameters": {
          "message": "🔴 Clique aqui (vermelho)"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "User Action",
        "parameters": {
          "message": "Digite SIM se clicou",
          "variable": "clicked"
        }
      }
    },
    {
      "id": "tracking_2",
      "type": "tracking",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Track Conversion",
        "parameters": {
          "trackingType": "a_b_test",
          "data": {
            "experimentId": "exp_button_color_001",
            "experimentName": "CTA Button Color Test",
            "variant": "{{variant}}",
            "converted": true
          }
        }
      }
    },
    {
      "id": "message_3",
      "type": "message",
      "position": { "x": 1500, "y": 100 },
      "data": {
        "label": "Result",
        "parameters": {
          "message": "✅ Teste registrado!\n\nVariante: {{variant}}\nClicou: SIM"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "tracking_1" },
    { "source": "tracking_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_1", "label": "true" },
    { "source": "condition_1", "target": "message_2", "label": "false" },
    { "source": "message_1", "target": "input_1" },
    { "source": "message_2", "target": "input_1" },
    { "source": "input_1", "target": "tracking_2" },
    { "source": "tracking_2", "target": "message_3" },
    { "source": "message_3", "target": "end_1" }
  ]
}

Teste: Execute várias vezes. Metade vê botão azul, metade vermelho. Sistema rastreia qual converte mais.

Parâmetros

Campo Tipo Obrigatório Descrição
trackingType string Sim Deve ser "a_b_test"
experimentId string Sim ID único do experimento
experimentName string Sim Nome descritivo
variant string Sim control, variant_a, variant_b
converted boolean Não Se usuário converteu

Exemplo: Pricing Test

Objetivo: Testar se preço de R$ 97 ou R$ 197 converte melhor.

{
  "name": "AB Test - Pricing",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Assign Price",
        "parameters": {
          "name": "price_variant",
          "value": "{{$random(['price_97', 'price_197'])}}"
        }
      }
    },
    {
      "id": "tracking_1",
      "type": "tracking",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Track Price Shown",
        "parameters": {
          "trackingType": "a_b_test",
          "data": {
            "experimentId": "exp_pricing_001",
            "experimentName": "Pricing Test",
            "variant": "{{price_variant}}"
          }
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Check Price",
        "parameters": {
          "variable": "price_variant",
          "operator": "equals",
          "value": "price_97"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Offer R$ 97",
        "parameters": {
          "message": "💰 Curso por R$ 97\n\nDeseja comprar?"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 150 },
      "data": {
        "label": "Offer R$ 197",
        "parameters": {
          "message": "💰 Curso por R$ 197\n\nDeseja comprar?"
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Response",
        "parameters": {
          "message": "Digite SIM ou NÃO",
          "variable": "response"
        }
      }
    },
    {
      "id": "condition_2",
      "type": "condition",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Check Purchase",
        "parameters": {
          "variable": "response",
          "operator": "equals",
          "value": "SIM"
        }
      }
    },
    {
      "id": "tracking_2",
      "type": "tracking",
      "position": { "x": 1500, "y": 100 },
      "data": {
        "label": "Track Conversion",
        "parameters": {
          "trackingType": "a_b_test",
          "data": {
            "experimentId": "exp_pricing_001",
            "experimentName": "Pricing Test",
            "variant": "{{price_variant}}",
            "converted": true
          }
        }
      }
    },
    {
      "id": "message_3",
      "type": "message",
      "position": { "x": 1700, "y": 100 },
      "data": {
        "label": "Success",
        "parameters": {
          "message": "✅ Compra confirmada!\n\nPreço testado: {{price_variant}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "tracking_1" },
    { "source": "tracking_1", "target": "condition_1" },
    { "source": "condition_1", "target": "message_1", "label": "true" },
    { "source": "condition_1", "target": "message_2", "label": "false" },
    { "source": "message_1", "target": "input_1" },
    { "source": "message_2", "target": "input_1" },
    { "source": "input_1", "target": "condition_2" },
    { "source": "condition_2", "target": "tracking_2", "label": "true" },
    { "source": "condition_2", "target": "end_1", "label": "false" },
    { "source": "tracking_2", "target": "message_3" },
    { "source": "message_3", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: 💰 Curso por R$ 97. Deseja comprar?
Usuário: SIM
Sistema: ✅ Compra confirmada! Preço testado: price_97

Resposta do Node

{
  "success": true,
  "action": "ab_test_tracked",
  "data": {
    "type": "a_b_test",
    "experimentId": "exp_pricing_001",
    "experimentName": "Pricing Test",
    "variant": "price_97",
    "converted": true,
    "userId": "user_123",
    "sessionId": "session_456",
    "timestamp": "2025-01-15T10:30:00.000Z"
  },
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Análise de Resultados

Calcular Conversion Rate

Control (R$ 97):
- Exposures: 500
- Conversions: 100
- Conversion Rate: 20%

Variant A (R$ 197):
- Exposures: 500
- Conversions: 75
- Conversion Rate: 15%

Winner: Control (R$ 97) - 20% vs 15%

Statistical Significance

Use chi-square test ou t-test para validar se diferença é estatisticamente significante (p-value < 0.05).

Sample Size Calculator

Para 95% confiança e 80% power: - Baseline: 10% conversion - Esperado: 12% conversion - Sample size: ~3,800 por variante

Boas Práticas

SIM: - Calcule sample size necessário antes - Rode experimento até atingir significância estatística - Teste uma variável por vez - Use 50/50 split para máximo power - Documente hipótese antes de iniciar

NÃO: - Não pare experimento cedo (mesmo se winning) - Não teste múltiplas variáveis simultaneamente - Não mude experimento durante execução - Não ignore significância estatística

Dicas

💡 Dica 1: Use calculadoras online de sample size (Optimizely, VWO) 💡 Dica 2: Rode por no mínimo 1-2 semanas para capturar padrões semanais 💡 Dica 3: Monitore external validity (resultados se mantêm pós-teste?) 💡 Dica 4: Combine com FEATURE_FLAG para progressive rollout 💡 Dica 5: Use Bayesian A/B testing para resultados mais rápidos

Próximo Node

FEATURE_FLAG - Feature flags para rollout controlado → COHORT - Análise por cohort → CONVERSION - Track conversions