Testes A / B no Android de A a Z

imagem

A maioria dos artigos sobre testes A / B é dedicada ao desenvolvimento da Web e, apesar da relevância dessa ferramenta para outras plataformas, o desenvolvimento móvel permanece injustamente distante. Vamos tentar eliminar essa injustiça descrevendo as principais etapas e revelando os recursos da implementação e condução de testes A / B em plataformas móveis.

Conceito de teste A / B


É necessário um teste A / B para testar hipóteses destinadas a melhorar as principais métricas de aplicativos. No caso mais simples, os usuários são divididos em 2 grupos controle (A) e experimental (B). Um recurso que implementa a hipótese é implementado apenas no grupo experimental. Além disso, com base em uma análise comparativa dos indicadores métricos para cada um dos grupos, é tirada uma conclusão sobre a relevância do recurso.

Implementação


1. Divida os usuários em grupos


Primeiro, precisamos entender como dividiremos os usuários em grupos na porcentagem correta, com a capacidade de alterá-los dinamicamente. Essa oportunidade será especialmente útil se, de repente, um novo recurso aumentar a conversão em 146% e for lançado, por exemplo, por apenas 5% dos usuários! Certamente, desejamos lançá-lo para todos os usuários e agora - sem atualizar os aplicativos na loja e os custos de tempo associados.

Obviamente, você pode organizar uma divisão no servidor e, sempre que precisar alterar alguma coisa, puxe os desenvolvedores de back-end. Mas, na vida real, o suporte geralmente é desenvolvido do lado do cliente ou de uma terceira empresa, e os desenvolvedores de servidores têm o suficiente para fazer, portanto nem sempre é possível ajustar rapidamente a divisão, trabalhando com terceiros ou, melhor ainda, quase nunca, então essa opção não é adequada para nós. E então o Firebase Remote Config vem em socorro!

imagem No Firebase Console, no grupo Crescer, há uma guia Configuração remota na qual você pode criar sua própria configuração que o Firebase entregará aos usuários de seu aplicativo.


A configuração é um mapa <chave de parâmetro, valor de parâmetro> com a capacidade de atribuir um valor de parâmetro de acordo com a condição. Por exemplo, para usuários com uma versão específica do aplicativo, o valor é X, para todos os outros - Y. Para obter mais informações sobre a configuração, consulte a seção correspondente da documentação .

imagem

Também no grupo Crescer, há uma guia Teste A / B. Aqui podemos executar os testes com todos os pães acima. As teclas do nosso Remote Config são usadas como parâmetros. Em teoria, você pode criar novos parâmetros diretamente no teste A / B, mas isso apenas adicionará confusão desnecessária; portanto, você não deve fazer isso, pois é mais fácil adicionar o parâmetro correspondente à configuração. O valor nele é tradicionalmente o valor padrão e corresponde ao grupo de controle, e o valor experimental do parâmetro, que não o padrão, é experimental.

imagem

Nota O grupo de controle geralmente é chamado de grupo A, o grupo experimental é chamado B. Como você pode ver na captura de tela, no Firebase o grupo experimental padrão é chamado de “Variante A”, o que introduz alguma confusão. Mas nada impede de mudar seu nome.

Em seguida, execute o teste A / B, o Firebase divide os usuários em grupos que correspondem a diferentes valores do parâmetro. Após receber a configuração no cliente, obtemos o parâmetro necessário e usamos o novo recurso com base no valor. Tradicionalmente, o parâmetro tem um nome correspondente ao nome do recurso e 2 valores: Verdadeiro - o recurso é aplicado, Falso - não é aplicado. Leia mais sobre as configurações dos testes A / B na seção correspondente da documentação .

2. Código


Não vamos nos concentrar diretamente na integração com o Firebase Remote Config - é descrito em detalhes aqui .

Vamos descobrir como organizar o código para o teste A / B. Se mudarmos a cor do botão, falar sobre a organização não fará sentido, porque não há nada de especial para organizar. Consideraremos uma variante na qual, dependendo do parâmetro da Configuração remota, a tela atual (para o grupo de controle) ou nova (para o experimental) é exibida.

Você precisa entender que, após a expiração do teste A / B, uma das opções da tela precisará ser excluída. Nesse sentido, o código deve ser organizado de forma a minimizar as alterações na implementação atual. Todos os arquivos associados à nova tela devem ser chamados com o prefixo AB e colocados em pastas com o mesmo prefixo.

Se falarmos sobre o MVP na camada de apresentação, será algo como isto:

imagem

A hierarquia de classes mais flexível e transparente parece ser:

imagem

BaseOrderStatusFragment conterá toda a funcionalidade da implementação atual, exceto métodos que não podem ser colocados em uma classe abstrata devido a limitações de arquitetura. Eles estarão localizados em OrderStatusFragment.

O AbOrderStatusFragment substituirá os métodos que diferem na implementação e possuem os necessários adicionais. Assim, na implementação atual, apenas a divisão de uma classe em duas será alterada e alguns métodos na classe base serão protegidos abertos em vez de privados.

Nota: se a arquitetura e o caso específico permitirem, você poderá criar uma classe base e herdar diretamente AbOrderStatusFragment de OrderStatusFragment.

Dentro da estrutura de tal organização, provavelmente é necessário desviar-se do CodeStyle aceito, o que é permitido neste caso, porque o código correspondente será excluído ou refatorado após a conclusão do teste A / B (mas, é claro, nos locais onde o CodeStyle é violado, vale a pena deixar um comentário)

Essa organização nos permitirá remover um novo recurso de maneira rápida e indolor, se for irrelevante, pois todos os arquivos associados a ele são fáceis de encontrar por prefixo e sua implementação não afeta a funcionalidade atual. Se o recurso melhorou a métrica principal e foi decidido deixá-lo, ainda precisamos trabalhar no corte da funcionalidade atual, o que afetará o código do novo recurso.

Para obter a configuração, vale a pena criar um repositório separado e injetá-lo no nível do aplicativo para que ele seja acessível em qualquer lugar, pois não sabemos quais partes do aplicativo afetarão futuros testes A / B. Pelas mesmas razões, vale a pena solicitá-lo o mais rápido possível, por exemplo, juntamente com as informações básicas necessárias para o funcionamento do aplicativo (geralmente essas solicitações ocorrem durante o splash, embora este seja um tópico holístico, mas é importante que existam em algum lugar).

Bem, e, é claro, é importante não esquecer de colocar o valor do parâmetro da configuração nos parâmetros do evento de análise, para que você possa comparar métricas

Análise de Resultados


Existem muitos artigos detalhando como analisar os resultados dos testes A / B, por exemplo . Para não nos repetirmos, simplesmente indicamos a essência. Você precisa entender que a diferença nas métricas nos grupos controle e experimental é uma variável aleatória, e não podemos concluir que o recurso seja relevante apenas com base no fato de que a métrica no grupo experimental é melhor. É necessário construir um intervalo de confiança (a escolha do nível de confiabilidade deve ser confiada aos analistas) para a variável aleatória descrita acima e realizar o experimento até que o intervalo esteja completamente no semiplano positivo ou negativo - então uma conclusão estatisticamente válida pode ser feita.

Armadilhas


1. Erro ao obter a configuração remota

Uma análise comparativa é realizada em novos usuários, uma vez que usuários com a mesma experiência do usuário e apenas aqueles que viram a única opção de implementação devem participar das experiências. Lembre-se de que receber a configuração é uma solicitação de rede e pode falhar; nesse caso, o valor padrão, tradicionalmente igual ao valor do grupo de controle, será aplicado.

Considere o seguinte caso: temos um usuário que o Firebase atribuiu ao grupo experimental. O usuário inicia o aplicativo pela primeira vez e a solicitação Configuração remota retorna um erro - o usuário vê a tela antiga. Na próxima inicialização, a solicitação Configuração remota é processada corretamente e o usuário vê uma nova tela. É importante entender que esse usuário não é relevante para o experimento, portanto, você precisa descobrir como filtrar esse usuário na lateral do sistema de análise ou provar que o número de usuários é insignificante.

De fato, esses erros ocorrem com pouca frequência e, muito provavelmente, a última opção combina com você, mas há um problema semelhante, porém muito mais urgente - o momento de obter a configuração. Como mencionado acima, é melhor manter a solicitação de configuração remota no início da sessão, mas se a solicitação demorar muito, o usuário ficará cansado de esperar e sairá do aplicativo. Portanto, você precisa resolver uma tarefa não trivial - para escolher um tempo limite pelo qual a solicitação de Configuração Remota é redefinida. Se for muito pequeno, uma grande porcentagem de usuários poderá estar na lista de irrelevantes para o teste, se for muito grande - corremos o risco de causar raiva. Reunimos estatísticas sobre o horário de recebimento da configuração:

imagem

Nota Dados dos últimos 30 dias. Número total de pedidos 673 529 . A primeira coluna, além das solicitações de rede, contém o recebimento da configuração do cache e, portanto, é eliminada do formulário de distribuição geral.

Dados do gráfico:


Milissegundos


Número de pedidos


200


227485


400


51038


600


59249


800


84516


1000


63891


1200


39115


1400


24889


1600


16763


1800


12410


2000


9502


2200


7636


2400


6357


2600


5409


2800


4545


3000


3963


3200


2699


3400


3184


3600


2755


3800


2431


4000


2176


4200


1950


4400


1804


4600


1607


4800


1470


5000


1310


> 5000


35375




2. Atualização remota Configuração remota

Você deve entender que o Firebase armazena em cache uma solicitação de configuração remota. O tempo de vida padrão do cache é de 12 horas. O tempo pode ser ajustado, mas o Firebase tem um limite de frequência de solicitações e, se for excedido, o Firebase nos banirá e retornará um erro na solicitação de configuração. possível para um número limitado de dispositivos).

Portanto, por exemplo, se queremos concluir o teste A / B e lançar um novo recurso em 100%, precisamos entender que a transição ocorrerá apenas dentro de 12 horas, mas esse não é o principal problema. Considere o seguinte caso: realizamos um teste A / B, concluímos e preparamos uma nova versão, na qual há outro teste A / B com a configuração correspondente. Lançamos uma nova versão do aplicativo, mas nossos usuários já possuem uma configuração em cache do teste A / B anterior e, se o cache ainda não tiver expirado, a solicitação de configuração não exibirá novos parâmetros e, novamente, os usuários serão atribuídos ao grupo experimental, que na primeira solicitação receberão os valores padrão da configuração e, no futuro, estragarão os dados da nova experiência.

A solução para esse problema é muito simples - você precisa forçar a solicitação de configuração ao atualizar a versão do aplicativo, redefinindo a vida útil do cache:

val cacheExpiration = if (isAppNewVersion) 0L else TWELVE_HOURS_IN_SECONDS FirebaseRemoteConfig.getInstance().fetch(cacheExpiration) 

Como as atualizações não são emitidas com tanta frequência, não excederemos os limites
Leia mais sobre esses problemas aqui .

Conclusões


O Firebase fornece uma ferramenta de teste A / B muito conveniente e simples que deve ser usada, prestando atenção especial aos gargalos descritos acima. A organização proposta do código minimizará o número de erros ao fazer alterações associadas ao ciclo de testes A / B.

Boa sorte a todos, testes A / B bem-sucedidos e aumento de 100,5% nas conversões.

Source: https://habr.com/ru/post/pt425501/


All Articles