Criando experimentos com a gema Split

Publicado por Leonardo Risch no dia dev

teste A/B

Aqui na Resultados Digitais realizamos diversos experimentos para melhorar sempre a experiência de nossos usuários. Um dos métodos para realizar isto é utilizando a gema Split.

O que é a gema split?

A gema Split serve para criarmos testes A/B , com isso podemos administrar o experimento através de uma interface onde acompanhamos os resultados parciais e decidir quando reiniciar, deletar ou definir um ‘vencedor’.

Quando concluímos quem ganhou o teste A/B, podemos escolher a versão para ficar em produção, necessitando apenas remover o código legado da versão perdedora.

Setup

Colocar no Gemfile

1
gem 'split'

Executar o comando bundle install

Configurando o split

O arquivo de configurações da gema fica no caminho config/initializers/split.rb. Neste arquivo será definido a instância do redis para consultar, qual será o contexto do teste A/B (conta/usuário/grupo), caminho para carregamento dos experimentos, entre outros.

Você pode ver todas as configurações disponíveis na documentação oficial

Criando um experimento

Para criar um experimento, você pode criar um arquivo YAML com o nome do experimento. Por exemplo:

1
2
3
4
5
6
7
8
9
# config/button_experiment.yml

button_experiment: # nome do experimento
   alternatives: [old, new] # nome das alternativas disponíveis para o teste A/B
   metadata: # dados variáveis conforme o experimento
     old:
       button: 'Comprar' # valor do botão para o teste `old`
     new:
       button: 'Veja mais' # valor do botão para o teste `new`

Para que o split reconheça este arquivo, você deve mapear o caminho no arquivo de configurações.

1
2
3
4
5
# config/initializers/split.rb

Split.configure do |config|
  config.experiments = YAML.load_file "config/button_experiment.yml"
end

Também é permitido passar um hash apenas no arquivo de configuração. Este exemplo mostra como fazer desta maneira.

Setando variáveis do experimento

Abaixo está a configuração padrão da gema para apresentar algum valor de componente que está inserido no metadata do arquivo:

1
2
3
4
5
<div class="experiment">
    <% ab_test('experiment') do |alternative, metadata| %>
         <%= button_tag(metadata['button'], alt: "Login!") %>
    <% end %>
</div>

Para o nosso contexto, criamos o arquivo app/helpers/split_helper.rb, que tem algumas funções para facilitar um pouco a leitura de busca dos dados do metadata.

Com isso podemos ler as variáveis do meta de diferente maneiras, simplificando a leitura de dados do experimento. Alguns exemplos que simplificamos são:

  • Busca de chave específicas no metadata

  • Busca de chaves do i18n no metadata

  • Busca de chaves de caminho de arquivos para renderizar

Apenas colocando essas funções, nos permite não ficarmos colocando diversos blocos para busca de um elemento no metadata do experimento. Você pode colocar os padrões que se adaptam ao projeto para simplificar a busca destes elementos.

Configurando as hipóteses do experimento

Para analisar se a hipótese é valida, todo experimento tem uma expectativa de sucesso..

A gema Split permite uma fácil visualização desses pontos. Ela possui um método finished que marca um ‘ponto’ para a ação mapeada e depois apresenta no relatório qual experimento está ganhando no ponto a ser comprovado.

Primeiro configuramos uma rota para enviarmos a informação quando o usuário realizar a ação mapeada:

1
2
# config/routes.rb
post '/experiment/finished', :to => 'split#experiment_finished', :as => :experiment_finished

Após isso, criamos o controller para aplicar o ponto para o experimento:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# controllers/split_controller.rb

class SplitController < SessionProtectedController

  def experiment_finished
    finished(experiment_name, reset: reset?)
    render nothing: true
  end

  private

  def experiment_name
    params.require(:experiment_name)
  end

  def reset?
    params.permit(:reset)
  end

end

A função reset serve para quando quisermos que troque o experimento da conta quando ela executar determinada ação, ou seja, se a conta tiver no grupo ‘old’ e execute uma ação que altere o valor do reset para true, ela irá trocar de grupo, indo para o ‘new’ ou algum outro que esteja configurado.

Para finalizar, temos um arquivo Javascript que marca o ponto para o experimento:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// assets/javascript/split_wrapper.js

var SplitWrapper = (function($) {
  'use strict';

  var _init = function(experimentName, reset) {
    _markPoint(experimentName, reset);
  },

  _markPoint = function (experimentName, reset) {
    if (typeof(reset) === 'undefined') {
      reset = false;
    }

    $.post(Routes.experiment_finished_path(), {
      experiment_name: experimentName,
      reset: reset
    });
  },

  return { init: _init}

})(jQuery);

Para marcar um ponto utilizar o método SplitWrapper.init('experiment');, com isso conseguimos identificar quem executou a ação que queríamos.

Analisando o experimento

Após termos todos os dados do experimento configurados, precisamos visualizar para tirar conclusões e confirmar se o experimento teve um resultado bom ou ruim. O Split apresenta um Dashboard com estas informações em tempo real.

Apenas adicionar a configuração:

1
2
3
# config/routes.rb

  mount Split::Dashboard, at: 'split'

Então conseguimos visualizar qual experimento está com melhores resultados:

Meu exemplo do Split

Sucesso! :smiley:

E você, tem alguma experiência com teste A/B? Conte para nós nos comentários.

Leonardo Risch

Leonardo Risch

Full Stack Developer

Comentários