Iniciando com Detox framework — 3/4

Utilize detox para saúde dos seus testes

Jhonatas Matos
Quia Digital
18 min readOct 8, 2020

--

Seguindo com a série de artigos para ajudar na configuração e execucação do detox, apresentamos a segunda parte onde iremos configurar as execuções para o Android.

Configurando um Ambiente de Desenvolvimento e Teste para Android

Este tutorial fornece algumas práticas fundamentais na configuração de um ambiente estável e confiável para operar testes automatizados de UI, usando os emuladores Android (Detox, em particular) — seja em um computador pessoal, local ou uma máquina poderosa de Integração Contínua (CI).

Note que operar testes UI automatizados está longe de ser como desenvolver apps para Android. Consequentemente, é possível não estar 100% de acordo com as recomendações aqui, mas, ainda assim, deveria considerá-las.

Instalação de Java

Esta é a etapa mais básica do processo, pois sem um SDK Java adequado instalado, nada derivado do Android funciona, pelo menos, não a partir da linha de comando, que é obrigatória para executar o Detox.

É pressuposto que Android precisa do Java 1.8 instalado.

Para verificar a versão do seu executável java, no console de linha de comando, execute:

O que precisa ser verificado é se o javaestá na pasta de instalação e que a saída contém algo como:

Ou seja, a versão é 1.8.x_abc

➢ Nota: Não confunda a versão Java potencialmente usada por seus navegadores etc. Para o Detox, o que a linha de comando vê é o que importa.

No MacOS, em particular, o java vem de OS e possivelmente de outros instaladores como homebrew, então é provável que algumas coisas não estejam corretas: veja esta publicação no stackoverflow.

Se o java não pode ser localizado ou nem sequer está instalado (ou seja, o comando falhou por completo), confira este tutorial.

Do contrário, se a versão simplesmente estiver errada, oriente-se por estas referências para Macs; considere aplicar a variável JAVA_HOME para fazer com que as coisas funcionem:

Android SDK

Caso tenha o Android Studio instalado, o SDK deve estar disponível em algum lugar na sua máquina*. No entanto, para os usuários de CI, possivelmente executando sem GUI, ou se simplesmente quiser esse software complexo em seu computador, é possível baixar o SDK e o conjunto de ferramentas separadamente. Ambos os casos são abordados no tutorial android do Google sobre o Android Studio. Para a opção das ferramentas puras, consulte a seção Command line tools onlineno fim da página.

Para mais ajuda na configuração o SDK, este tutorial pode ser útil.

Seja qual for a opção e plataforma escolhida (Mac, Linux ou Windows), a preferência é que, eventualmente, 2 coisas sejam configuradas:

  • O trajeto ao diretório raiz do SDK deve estar situado na variável ambiente do ANDROID_SDK_ROOT.
  • O trajeto ao diretório raiz do SDK deve estar localizado no PATH global em seu computador.

* Verifique o conteúdo das seguintes variáveis de ambiente: ANDROID_SDK_ROOT e ANDROID_HOME.

Emuladores (AOSP) Android

A automatização de aplicativos Mobile necessita de um dispositivo Android para execução. Caso ainda não possua um, é necessário configurar um emulador. Mas calma, não instale o modelo padrão ainda: primeiro leia com atenção.

Foi provado por muito tempo que para a automatização, a qual requer um ambiente estável e determinado, os emuladores do Google que funcionam com Google API simplesmente não fornecem o que é necessário. Seja com o Google Play Services já instalado — que tende a exigir bastante da CPU, ou mesmo do teclado gboard do Google — que é completo, mas abundante. Esse tipo de aplicativo incentiva a imprevisibilidade nos testes, que somos desesperados para evitar na automatização.

Felizmente, a equipe Android do Google oferece uma boa alternativa: Emuladores de AOSP (Projeto Open-Source do Android). Mesmo que possivelmente falte alguns dos serviços extensos do Google, e seja menos excessivo, nós recomendamos usar apenas esta variedade de emuladores para executar testes de automação/Detox. Estes podem ser instalados ao lado dos emuladores regulares.

Abaixo temos uma comparação visual entre os dois — um emulador de SDK 28 (Android 9) AOSP (esquerdo) vs. um emulador com as APIs do Google instalado (direito):

Aqui é mostrado como instalá-los usando a linha de comando:

Enquanto for possível fazê-lo usando o Android Studio, mudaremos o foco para a linha de comando, já que ela também é boa para máquinas CI sem cabeça.

  1. Encontre sua pasta “home” no Android — situada normalmente no ANDROID_HOME, a variável de ambiente, ou em sua sucessora ANDROID_SDK_ROOT. Se a ANDROID_HOME não está configurada, ajuste por conta própria ou execute os seguintes comandos após aplicar o cd na pasta home.
  2. Primeiramente: Atualize seu emulator executável para a versão mais recente.

Nota: Não tem problema se a versão do emulador não estiver emparelhada com a versão do SDK, ou de ferramentas de plataforma que tenha instalado atualmente (por exemplo: 30.x.x vs. SDK 29).

3. Instale a imagem do emulador sem as APIs do Google:

  • Com o ;android-28;, declaramos SDK 28 aqui, mas outros APIs são suportados da mesma forma.
  • A parte do ;default;substitui o ;google-apis;, o padrão, que importa aqui.

4. Crie um emulador (isto é, AVD — Dispositivo Virtual Android):

PIXEL_API_28_AOSP é só uma sugestão para um nome. Qualquer nome funciona, até mesmo Pixel_API_28 — mas, pode ser necessário ter que apagar um emulador existente que não seja do AOSP. De qualquer forma, o nome usado na configuração do Detox (tipicamente no package.json) deve ser idêntico a este.

  • d-pixelinstalará um emulador com as specs de um dispositivo Pixel-1. Outras specs podem ser usadas.
  • — package é o pretexto mais importante: tenha certeza de usar o mesmo valor que foi usado na parte 2 acima, junto de ;default;.

➢ Execute o avdmanager create — helppara a lista completa das opções.

5. Inicie o emulador:

Isto não é obrigatório, certamente, mas é sempre bom iniciar o emulador ao menos uma vez antes de executar testes automatizados. A seção abaixo discutirá sobre otimização do bootstraping nos emuladores.

A esse ponto, deve ser possível iniciar o emulador do Android Studio, mas isso também pode ser feito a partir de uma linha de comando em um console, como explicado nas orientações abaixo.

➢ Acompanhe este tutorial para detalhes sobre o emulador executável.

Instalando o Android Studio

Todos os detalhes não serão explorados, mas uma vez que a imagem apropriada está instalada usando o sdkmanager, a opção se torna disponível no diálogo de criação do AVD (veja a coluna Target da tela de Configuração do Dispositivo Virtual abaixo):

Certifique-se de atualizar seu emulador executável para a versão mais atual: Caso não esteja atualizado, uma mensagem é enviada dizendo: “Atualização Disponível” sob a coluna status, em vez de “Instalado”:

Nota: Não tem problema se a versão do emulador não estiver emparelhada com a versão do SDK ou das ferramentas de plataforma instaladas atualmente (por exemplo: 30.x.x vs. SDK 29).

Início Rápido do Emulador

Se o sistema permite um ponto de recuperação (por exemplo, em computador pessoal ou em sistema CI, onde é possível iniciar a partir de imagens pré- configuradas, que podem ser ajustadas), é extremamente recomendado configurar snapshots de início rápido para qualquer emulador que for usado em testes de automação.

O início rápido poupa uma quantidade considerável de tempo que seria desperdiçado quando o emulador inicia normalmente. O conceito se destaca em ambientes que conseguem uma execução paralela de testes em múltiplos emuladores sendo executados simultaneamente (como quando o Detox opera com múltiplos operadores de Jest).

Isso é algo que realmente recomendamos usar no próprio emulador do que na linha de comando, mas usaremos as duas opções.

Em todo o caso, o princípio geral que indicamos é:

  1. Habilite o auto-save no emulador instalado/funcionando.
  2. Inicie e quando estiver estável encerre — um snapshot é salvo como resultado.
  3. Desative o auto-save, de modo que, futuros snapshots testados não serão salvos.

Configurando um snapshot de início rápido do Emulador

Comece iniciando um emulador recém configurado. Espere até estabilizar. Ao executar, vá em configurações (3 pontos na barra lateral) > Snapshots >Settings. Caso ainda não esteja configurado selecione Yes na opção auto_save. Com isso provavelmente uma janela será aberta pedindo para reiniciar — escolha Yes. O emulador irá reiniciar e salvar um snapshot.

Repita esse processo depois que o emulador estiver de volta, mas defina No na opção de auto_save. Permita que ele reinicie mais uma vez: ele irá inicializar imediatamente no estado salvo como um snapshot anteriormente.

Também é possível tentar por estas fontes alternativas para esse processo:

Configurando um snapshot de início rápido pela linha de comando

É um pouco mais difícil, mas também é aplicável mesmo em máquinas sem UI.

  1. Localize a config.ini do AVD
  2. Usando um editor de texto à escolha, mude ou adicione estes conjuntos de valores chave:

➢ Na prática, forceFastBoot=yes e forceColdBoot=no devem ser suficientes.

3. No diretório inicial do AVD, crie ou edite outro arquivo ini chamado quickbootChoice.ini com o seguinte conteúdo:

4. Agora que tudo está no lugar, inicie o emulador uma vez (no modo verbose) e espere que ele carregue totalmente. Em seguida, desligue-o e certifique-se que o estado foi salvo.
5. Por último, mas não menos importante, volte ao ckbootChoice.ini e mude para:

Aviso

Depois de atualizar o binário do emulador para uma versão mais recente, ele geralmente considera todos os snapshots existentes inválidos.

Isso pode ser resolvido excluindo e recriando os snapshots conforme explicado ou recriando os AVDs completamente.

Orientações

Localizando o diretório home do AVD

Cada AVD gerado pelas ferramentas Android possui o próprio diretório, onde o conteúdo associado é armazenado:

Arquivo de configuração (isto é, config.ini)

  • Imagens do snapshot
  • índice do cartão SD

Para nomear alguns.
Em máquinas Mac, o diretório de AVD é normalmente traçado para:

(por exemplo: User/root/.android/avd/Pixel_API_28_AOSP.avd/)

O trajeto deve ser similar em máquinas de Linux, mesmo que $HOMEnão seja /Users/root mas tipicamente /home/root.

(por exemplo: home/root/.android/avd/Pixel_API_28_AOSP.avd/)

Iniciando emulador através da linha de comando

  • Os seguintes exemplos aplicam-se para ambos Mac e Linux, e devem ser similares no Windows.
  • É suposto que o nome do emulador seja Pixel_API_28_AOSP. Se não for, ajuste os nomes de acordo:

Atalho para inicializar um emulador visível e em verbose em um sistema com suporte de GUI

Atalho para iniciar um emulador em verbose e sem cabeça em um sistema sem UI no Linux

Verificando se o snapshot de início rápido do emulador foi salvo

Se ao executar seu emulador no modo verbose a partir de um shell, é fácil verificar o estado em que foi salvo seguindo os registros. Particularmente, ao encerrar o emulador, este registro declara o estado em que foi salvo:

➢ Como referência, quando o estado não for salvo, a saída típica é:

➢ Pode ser o resultado de uma configuração inadequada ou da inicialização de um emulador em que o argument -read-only foi fornecido.

Detox para Android

Alterações Inesperadas⚠️

Caso esteja instalando Detox para o Android pela primeira vez, é possível pular até a seção de configuração.

➢ Siga o Tutorial de Migração para instruções de como atualizar versões antigas.

  • Na versão 11 é alterado para o Android Espresso das novas bibliotecas de suporte do androidx.* do Android. Isso é feito a fim de permanecermos atualizados com os recursos e reparos mais recentes do Google, na esperança de usá-las para melhorar nosso próprio suporte do Android (que melhora a cada dia!).
  • Na versão 10, Kotlin é indispensável para integrar o Detox em seu projeto Android. No mínimo, inclua o plugin do gradle do Kotlin em seu projeto, como será visto posteriormente. Entretanto, é bom levar em conta ao atualizar que essa é uma alteração inesperada. De qualquer forma, não se preocupe com o impacto em seu aplicativo, pois, a menos que use efetivamente o Kotlin em seu próprio código nativo, não haverá impacto no APK final, em termos de tamanho e contagem de métodos.
  • A partir da versão 7 é requisitado o plugin gradle do Android 3.0.0 ou mais recente. Com essa alteração não é possível suportar versões anteriores do Plugin do Android para o Gradle

https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html

Para suporte de versões mais antigas do Plugin do Android para o Gradle use detox@6.x.x como alternativa (tutorial da versão anterior aqui).

Nota: De forma geral, todas as antigas versões principais são consideradas interrompidas; somente a versão principal mais recente do Detox é suportada.

Configuração

  1. Introdução

Siga os passos básicos do Ponto de Partida, assim como a configuração do ambiente e das ferramentas.

2. Para aplicar a Configuração Detox

Caso escolha aplicar a configuração em um .detoxrc.json ou inseri-la em um package.json no projeto (sob a seção detox ), isto é como a configuração deve aparentar para o Android:

➢ Para uma explicação abrangente das configurações do Detox, consulte o tutorial exclusivo de referência API.

Preste atenção no -DtestBuildType, escolha entre debug ou release de acordo com o tipo do apk principal.

Os seguintes tipos de dispositivos podem ser usados para controlar aparelhos Android:

  • android.emulator . Inicialização em lote do emulador Android SDK (AVD) com o name fornecido, por exemplo Pixel_API_28.
  • android.attached . Conecte-se a um dispositivo Android já vinculado. O dispositivo deve estar listado na saída de comando do adb devicespelo name fornecido. Use esse padrão para conectar ao emulador do Genymotion. A propriedade adbName aceita um padrão de expressão normal que permite especificar o arranjo de candidatos que deseja conectar. Use essa propriedade para executar testes paralelos em múltiplos aparelhos conectados.

Para obter um exemplo completo, consulte o aplicativo de exemplo do Detox.

2a. Para usar variações do produto

Caso esteja usando um productFlavors, a configuração precisa ser aplicada de forma diferente. Esse exemplo mostra como uma variação de produto beta deve aparentar para ambos debug e versões de tipos de estruturas:

3. Para adicionar dependências Nativas do Detox

Ao iniciar o Detox 12.5.0, ele é enviado como um .aarpré-compilado. Para configurar o Detox como uma dependência de compilação, contudo — confira a sessão Configurando o Detox como uma dependência de compilação no fim da página.

No script de estrutura raiz (isto é, build.gradle ), registre ambos google() e pontos de referência em todo o projeto:

Em seu script de estrutura do aplicativo (isto é, app/build.gradle ) adicione isso na seção dependencies :

… e adicione isso à subseção defaultConfig :

Esteja ciente de que mindSdkVersion precisa ser, no mínimo, 18.

4. Adicione o Kotlin

Se o projeto ainda não suporta Kotlin, adicione o plugin Gradle do Kotlin para o classpath no script de estrutura raiz (isto é, android/build-gradle ):

Nota: A maioria dos tutoriais aconselham definir uma constante de KotlinVersion, como no exemplo, mas isso não é obrigatório.

Repare que Detox foi testado para versão 1.1.0 do Kotlin ou mais recente!

5. Crie uma Classe de Teste do Detox

Adicione o arquivo android/app/src/androidTest/java/com/[your.package]/DetoxTest.java e preencha assim como no aplicativo de exemplo do detox para RN. Não esqueça de mudar o nome da pasta para o do seu projeto.

6. Disponibilize o tráfego da limpeza de texto (não criptografado) para o Detox

Iniciar o Android SDK v28; o Google desabilitou todo o tráfego em rede de limpeza de texto por padrão. A menos que explicitamente configurado, todo o tráfego de saída das aplicações não encriptadas (isto é, sem TLS usando HTTP ao invés de HTTPS) é bloqueado pelo aparelho.

Para que o Detox funcione, seu código de teste que está sendo executado no aparelho deve conectar-se no host executor de testes pela interface(*) virtual do localhost usando um tráfego simples de HTTP. Portanto, a seguinte configuração de isenção da rede de segurança deve ser aplicada:

Em um arquivo de recurso xml, por exemplo android/app/src/main/res/xml/network_security_config.xml :

No AndroidManifest.xmldo aplicativo

Consulte o aplicativo de exemplos Detox para um modelo de como implementar de forma efetiva.

Nota: se configurado corretamente, de modo algum comprometerá as configurações de segurança do aplicativo.

Para detalhes completos, confira o tutorial do Android para configurar a segurança, e o artigo dedicado no blog de desenvolvedores Android.

(*) 10.0.2.2 para emuladores Google, 10.0.3.2 para emuladores Genymotion.

7. Proguard (Minificação)

Para aplicativos em processo de minificação usando Proguard, de forma que o Detox funcione em novas versões, disponibilize algumas regras de configuração proguard do Detox aplicando o arquivo de configuração padrão acima do seu. Normalmente, isso é definido usando a declaração proguardFiles no tipo de estrutura que disponibiliza minificação em seu app/build.gradle :

8. Suporte do Test Butler (Opcional)

Se, quando estiver configurando o ambiente de trabalho, ocorrer a seleção dos emuladores do Google com uma imagem de AOSP como o alvo de teste, como foi recomendado, nós incentivamos fortemente a integração de um Test Butler: pelo menos, a fim de evitar crashs e erros de ANR. Eles são um ponto fraco nos testes de UI em todo o Android, como, quando mostrado, tornam a UI completamente inacessível (dessa forma causando falhas em massa nos testes).

Configurar o Test Butler para trabalhar com Detox é um pouco diferente de como foi explicado em seus tutoriais. O processo, como um todo, tem duas etapas:

1. Instalar o APK do aplicativo do Test Butler no dispositivo de teste.

2. Integrar as bibliotecas do Test Butler em seu próprio APK de teste, e inicializá-lo em um executor de testes personalizado (como explicado).

A parte da biblioteca pode ser facilmente alcançada como explicado (isto é, usando o androidTestImplementation do Gradle). O mesmo vai para a iniciação. Quanto ao APK, o uso sugerido do androidTestUtil do Gradle é escasso ao ser executado com Detox (testes não nativos à instrumentação). Nesse caso temos estas alternativas.

1° Solução: Imagens Pré-Configuradas

Caso tenha controle sobre os snapshots do emulador, simplesmente baixe (veja o tutorial do Test Butler) e instale o APK do Test Butler uma vez (por exemplo use o adbinstall -r -t path/to/test-butler-app.apkx ), e salve uma versão atualizada do snapshot. Esta é a melhor solução.

➢ Nota: será necessário repetir este processo caso a versão do Test Butler seja atualizada futuramente.

2° Solução: Instalação Dinâmica

Supondo que o APK esteja disponível no sistema, é possível fazer com que o Detox o instale em todos os emuladores-alvo em execução, utilizando utilBinaryPaths na sua configuração de Detox. Exemplo:

➢ Consulte o nosso tutorial de configuração para mais detalhes sobre utilBinaryPaths .

Em relação a tornar o APK disponível ainda não temos nenhuma solução efetiva, por enquanto (mas está no processo). Porém há algumas soluções:

a). Em um script personalizado, baixe o APK diretamente do Bintray com antecedência, como sugerido na guia do Test Butler. Por exemplo (em um Mac/Linux):

A instalação global do Jest é um lugar recomendado para esse tipo de coisa.

➢ Se for decidido seguir este trajeto, é recomendado adicionar ./temp/test-butler-app.apk ao .gitignorede maior relevância.

b). (Não recomendado) Adicione-o ao código fonte (por exemplo o git), como parte do repositório.

Para configurar o Detox como dependência de compilação

Isto é uma alternativa ao processo de instalação descrito na seção anterior, para adicionar Detox como uma dependência.

No settings.gradle do seu projeto, adicione:

No seu script raiz (isto é, build.gradle ), registre google() como um ponto de referência repositório em todos os projetos:

No script do seu aplicativo (isto é, app/build.gradle ) adicione isto na seção dependencies :

No script do seu aplicativo (isto é, app/build.gradle ) adicione esta chave à subseção do defaultConfig :

Esteja ciente que minSdkVersion necessita estar pelo menos na versão 18.

Correção de erros

Problema: Duplicate files copied in...

Se surgir um erro como esse:

É preciso adicionar isso à seção android do seu android/app/build.gradle:

Problema: Conflitos da versão do stdlib de Kotlin

Os problemas e as definições aqui são diferentes se você estiver usando Detox como um artefato dependente de pré-compilação (isto é, .aar ) — que é o padrão, ou compilando você mesmo.

Resolução para uma dependência de pré-compilação ( .aar )

De todos as variações de implementações do Kotlin, o Detox atribui o mais recente, isto é: kotlin-stdlib-jdk8. Se sua configuração do Android falhar devido aos conflitos com as implementações vindas de outras dependências ou mesmo de seu próprio aplicativo, considere adicionar uma exclusão às “outras” dependências ou ao próprio detox, por exemplo:

Detox deve funcionar bem com kotlin-stdlib-jdk7.

Uma saída de erro típica formada pelo Gradle neste caso é a fornecida, por exemplo, em #1380:

(O projeto depende indiretamente de versões diferentes do kotlin-stdlib , assim como a 1.3.0, 1.3.30, 1.2.60 ).

Resolução para um subprojeto de compilação

O Detox requer a biblioteca padrão do Kotlin como sua própria dependência. Devido aos vários conjuntos que o Kotlin está lançando, múltiplas dependências frequentemente criam conflitos.

Por isso, o Detox permite a especificação exata da biblioteca padrão usar dois globais do Gradle: detoxKotlinVersion e detoxKotlinStdlib . É possível definir ambos no arquivo script estrutural raiz ( android/build.gradle ):

Problema: O aplicativo carrega, mas os testes não executam no SDK >= 28

Como relatado na edição #1450, algumas vezes o aplicativo que está sendo testado iniciaria em um emulador/dispositivo quando o Detox é executado, mas o executor de testes suspenderá e não irá iniciar a execução dos testes.

Mais especificamente, quando isto acontecer:

  1. O Detox e o executor de testes iniciam com sucesso, juntamente com o aplicativo que está sendo executado (a menos que launchApp:false for passado para detox.init() ), mas o primeiro teste simplesmente fica paralisado para sempre (como explicado).
  2. Eventualmente, o executor de testes seria interrompido.

3. Os últimos registros de Detox, relatados antes da interrupção, indicariam que o dispositivo não se conectava ao executor de testes no host. Por exemplo:

  • O passo principal para reparar esse problema é voltar para a etapa 6 neste tutorial, que discute a rede de segurança.
  • De outra forma, o atributo android:usesCleartextTraffic="true" pode ser configurado na tag <application> do AndroidManifest.xml do aplicativo, porém isso é fortemente desencorajado.

Problema: Detox não pôde encontrar o APK de teste

Pode ser gerada uma mensagem de erro como essa: detox[53027] ERROR: Error:'android/app/build/outputs/androidTest/x86_64/debug/app-x86_64-debug-androidTest.apk' could not be found, did you run ‘./gradlew assembleAndroidtest'?

Nesse caso o testBinaryPath pode ser usado na configuração para substituir o binaryPath e apontar diretamente para o APK de teste.

--

--